For this program I have three data files. The first has a list of numbers, the second is a list of numbers with an add (A) or delete (D) command. I have to put the numbers from the first file into the third file, then update the final file based on the commands and numbers in the second file. The third file cant have duplicates and must be sorted while values are being inserted. Here are the functions I have, I'm having difficulty getting the items stored into the array without duplicates. The array must be statically sized, I did a #define of max size 2000 which is more than enough to handle the numbers I need. Thanks so much! If I should upload the main let me know, but I'm fairly certain the problem lies in one of these functions.
int search(int value, int list[], int n) // returns index, n is logical size of array
{
int index = -1;
for(int i = 0; i < n; i++)
{
if(value == list[i])
{
index = i;
return index;
}
}
return index;
}
void storeValue(int value, int list[], int& n)
{
int i = n;
for(; i > 0 && list[i - 1] < value; i--)
{
list[i] = list[i - 1];
}
list[i] = value;
n++;
}
void deleteValue(int loc, int list[], int n)
{
if(loc >= 0 && loc < n)
{
for(int i = loc; i < n - 1; i++)
list[i] = list[i +1];
n--;
}
}
UPDATE: Now duplicates are being stored, but only for some numbers.
For example: my 3rd file is: 1,2,8,8,9,101,101,104,etc.
The output should be: 1,2,8,9,101,104,etc
value: value to be inserted
list[]: array being modified (must be static)
n: logical size of array
I can't figure out why some numbers are duplicated and others aren't
In my main, I run the search function and if a -1 is returned (the value isn't already found) then I run the storeValue function.
Here are my updated functions:
int search(int value, int list[], int n) // returns index
{
int index = -1;
for(int i = 0; i < n; i++)
{
if(value == list[i])
{
index = i;
return index;
}
}
return index;
}
void storeValue(int value, int list[], int& n)
{
int i = n;
for(; i > 0 && list[i - 1] > value; i--)
{
list[i] = list[i - 1];
}
list[i] = value;
n++;
}
void deleteValue(int loc, int list[], int& n)
{
if(loc >= 0 && loc < n)
{
for(int i = loc; i < n; i++)
{
if (i == loc)
{
list[i] = list[i + 1];
i++;
}
}
n--;
}
}
In your deleteValue function, you are deleting the value, but will end up with a duplicate because you are just reassigning the current index to the next value. For example, if you have the array:
char array[3] = [1, 2, 3];
and you wanted to delete the second integer, your function currently would output this:
[1, 3, 3]
What you want to do is make a new array and loop through your entire list, making sure to leave out the last element like so:
char* deleteValue(int loc, int list[], int n)
{
char* newArray[n - 1];
if (loc >= 0 && loc < n)
{
for (int i = 0; i < n - 1; i++)
{
if (i == loc) // You have arrived at the element that needs to be deleted
{
newArray[i] = list[i + 1];
i++; // So we skip over the deleted element
}
else
newArray[i] = list[i];
}
}
return newArray;
}
And this should take care of the case where the last value is duplicated.
Related
I tried to implement number of inversions in an array, using merge sort.
Every time I execute this code, I get different value of the number of inversions. I am not able to figure out the reason for this. Please have a look at the code and tell me the mistake.
#include<stdio.h>
#include<iostream>
using namespace std;
int count =0;
void merge(int A[],int start,int mid,int end)
{
int size1 = mid-start+1;
int size2 = end-(mid+1)+1;
int P[size1];
int Q[size2];
for(int i=0;i<size1;i++)
P[i]=A[start+i];
for(int j=0;j<size2;j++)
Q[j]=A[mid+j+1];
int k = 0;
int l = 0;
int i =0;
while(k<mid && l<end)
{
if(P[k]>Q[l])
{
A[i] = Q[l];
l++; i++;
count++;
}
else
{
A[i] = P[k];
k++; i++;
}
}
}
void inversions(int A[],int start,int end)
{
if(start!=end)
{
int mid = (start+end)/2;
inversions(A,start,mid);
inversions(A,mid+1,end);
merge(A,start,mid,end);
}
}
int main()
{
int arr[] = {4,3,1,2,7,5,8};
int n = (sizeof(arr) / sizeof(int));
inversions(arr,0,n-1);
cout<<"The number of inversions is:: "<<count<<endl;
return 0;
}
int k = 0;
int l = 0;
int i =0;
while(k<mid && l<end)
{
if(P[k]>Q[l])
{
A[i] = Q[l];
l++; i++;
count++;
}
else
{
A[i] = P[k];
k++; i++;
}
}
Few mistakes here, i starts from start and not 0. k must loop from 0 till size1 and not till mid. Similarly, l must loop from 0 till size2 and not till end. You are incrementing count by 1 when P[k] > Q[l] but this is incorrect. Notice that all the elements in array P following the element P[k] are greater than Q[l]. Hence they also will form an inverted pair. So you should increment count by size1-k.
Also, the merge procedure should not only count the inversions but also merge the two sorted sequences P and Q into A. The first while loop while(k<size1 && l<size2) will break when either k equals size1 or when l equals size2. Therefore you must make sure to copy the rest of the other sequence as it is back into A.
I have made the appropriate changes in merge and pasted it below.
void merge(int A[],int start,int mid,int end)
{
int size1 = mid-start+1;
int size2 = end-(mid+1)+1;
int P[size1];
int Q[size2];
for(int i=0;i<size1;i++)
P[i]=A[start+i];
for(int j=0;j<size2;j++)
Q[j]=A[mid+j+1];
int k = 0;
int l = 0;
int i = start;
while(k<size1 && l<size2)
{
if(P[k]>Q[l])
{
A[i] = Q[l];
l++; i++;
count += size1-k;
}
else
{
A[i] = P[k];
k++; i++;
}
}
while (k < size1)
{
A[i] = P[k];
++i, ++k;
}
while (l < size2)
{
A[i] = Q[l];
++i, ++l;
}
}
int P[size1];
int Q[size2];
VLA (Variable length arrays) are not supported by C++. size1 and size2 are unknown during compile time. So, each time they get a different value and hence the difference in output.
Use std::vector instead
std::vector<int> P(size1, 0); //initialize with size1 size
std::vector<int> Q(size2, 0); //initialize with size2 size
I have to make a method that sorts an array of values going from lowest value to the highest. The way these functions are supposed to work is that it grabs each value, tries to put them in rising order going from left to right by shifting every bigger value to the right.
I have made the following functions:
int findIndex(double *arr, double num, int length)
{
for (int i = 0; i < length; i++)
{
if (arr[i] > num)
return i;
}
return length - 1;
}
void placeOnIndex(double *arr, double num,int index, int length)
{
if (length > 1 && arr[index] != num)
{
for (int i = length - 1; i > 0; i--)
{
arr[i] = arr[i - 1];
}
arr[index] = num;
}
}
void insertSort(double* arr, int length)
{
for (int ix = 0; ix < length; ix++)
{
double num = arr[ix]; //Current value to put as far to the left as possible
int index = findIndex(arr, num, ix+1); //Locates index to put it
placeOnIndex(arr, num, index, ix+1); //Uses the index to put in the right place
}
}
void main()
{
double arr[4] = {1,8,4,5};
insertSort((arr), 4);
}
My problem is that the output with this array becomes:
1,1,5,8
Apparently it sometimes overrides the second element in my array. Sometimes it works and sometimes it doesn't. If the array is longer even more values are overridden.
I'm sorry if it looks confusing, english isn't my native tongue.
This line
for (int i = length - 1; i > 0; i--)
causes all the elements to move right, not just the ones that should move.
You need
for (int i = length - 1; i > index; i--)
I am supposed to get the output 8, 6. But I get 8,9 when this code is run. Why am I getting the out put 8,6 and how can I fix the code to make the output become 8,9.
int inputarray[]={9,8,9,9,9,9,6};
int length = 7;
int value = 9;
void arrayShift(int arr[], int length, int value)
{
for(int i = 0; i<length; i++)
{
if(arr[i] == value)
{
for (int k = i; k<length ; k++)
{
arr[k] = arr[k+1];
}
arr[length-1] = 0;
}
}
}
When shifting array, you may replace first element (containing number equal to value) with the same value from other element. In that case, you need to restart iteration on this element again, e.g.:
void arrayShift(int arr[], int length, int value)
{
for(int i = 0; i<length; i++)
{
if(arr[i] == value)
{
for (int k = i; k<length-1 ; k++)
{
arr[k] = arr[k+1];
}
arr[length-1] = 0;
i--; // <-- this
}
}
}
Your algorithm for shifting is wrong: you fail to adjust i on removal. In addition, it is rather inefficient: you can do this in a single loop with two indexes - r for reading and w for writing. When you see the value you want to keep, adjust both the reading and the writing index. Otherwise, increment only the reading index.
Once the reading index reaches the count, the writing index indicates how many items you have left. You need to return it to the caller somehow, otherwise he wouldn't know where the actual data ends. You can return the new length as the return value of your function, or take length as a pointer, and adjust it in place.
int arrayShift(int arr[], int length, int value) {
int r = 0, w = 0;
for (; r != length ; r++) {
if (arr[r] != value) {
arr[w++] = arr[r];
}
}
return w;
}
Here is how you call it:
int inputarray[]={9,8,9,9,9,9,6};
int length = 7;
int value = 9;
int newLen = arrayShift(inputarray, length, value);
for (int i = 0 ; i != newLen ; i++) {
printf("%d ", inputarray[i]);
}
printf("\n");
Demo.
I am creating a small program that is supposed to sort integers in an array in ascending order, but I am extremely stuck on the algorithm that I am supposed to use. I cannot iterate through the array, I must instead use a recursion function. I am allowed to have an auxiliary function that can find the smallest index in the array, which I have done successfully, but I am having the hardest time figuring out how to use that function to sort my array in the recursion function. Here is the code that I have so far, I understand that my sortIntegers function is way off.
int main()
{
int numbers[] = {8, 2, 5, 1, 3};
sortingIntegers(numbers, 5);
return 0;
}
void sortingIntegers(int *list, int size) {
if (size == 1) {
for (int i = 0; i < size; i++) {
cout << list[i] << ", ";
}
} else {
for (int z = 0; z < size; z++) {
if (list[size - 1] == smallestIndex(list)) {
for (int y = 0; y < size; y++) {
swap(list[z], list[y]);
}
}
}
sortingIntegers(list, size - 1);
}
}
int smallestIndex(int *array) {
int smallest = array[0];
for (int i = 1; i < sizeof(array); i++) {
if (array[i] < smallest) {
smallest = array[i];
}
}
return smallest;
}
int main()
{
int numbers[] = {8, 2, 5, 1, 0};
sortingIntegers(numbers, 0, 5);
for (int i=0;i<5;i++)
cout << numbers[i] << ' ';
return 0;
}
void sortingIntegers(int *list, int left, int size) {
if (left == size)
return;
int smallest = smallestIndex(list, left, size);
int c = list[smallest];
list[smallest] = list[left];
list[left] = c;
sortingIntegers(list, left+1 ,size);
}
int smallestIndex(int *array, int left, int size) {
int smallest = array[left];
int smIndex = left;
for (int i = left+1; i < size; i++) {
if (array[i] < smallest) {
smallest = array[i];
smIndex = i;
}
}
return smIndex;
}
That's my solution based on yours. First of all sizeof(array) returns the size of pointer. Second I return the index of the smallest item, not it's value, then I swap it with the first element in list. And then I call the sorting for the list starting with another element (the left parameter), because I know that the list up to left-1 is already sorted.
A fully recursive solution:
To sort an array, find the smallest element and swap it to the first position. Then sort the rest of the array, until there is a single element left.
To find the smallest element in an array, take the smallest of -the first element and -the smallest element in the rest of the array, until there is a single element left.
int SmallestIndex(int Array[], int From, int To)
{
if (From == To-1)
return From; // Single element left
// Index of the smallest in the rest
int Index= SmallestIndex(Array, From + 1, To);
// Index of the smallest
return Array[From] < Array[Index] ? From : Index;
}
void Sort(int Array[], int From, int To)
{
if (From == To-1)
return; // Single element left
// Locate the smallest element
int Index= SmallestIndex(Array, From, To);
// Swap it to the first place
int Swap= Array[Index]; Array[Index]= Array[From]; Array[From]= Swap;
// Sort the rest
Sort(Array, From + 1, To);
}
Call Sort with (Array, 0, N).
You can use this snippet to sort an array using recursion. It's not difficult you need to think like this way if your array length is N recursion sort N - 1 length array and you have to sort only one element that is N or you can say the last element. I give you an example it will help you suppose you have to sort this array = [50, 40, 10, 30, 20] if recursion gives you array = [10,30,40,50,20] this array you just need to place 20 in a correct position to sort the array.
private static void sort(int[] array, int length) {
if (length == 1) return;
sort(array, length - 1);
var lastIndex = length - 1;
for (int index = lastIndex; index > 0; index --){
if (array[index] < array[index - 1]){
int temp = array[index];
array[index] = array[index - 1];
array[index - 1] = temp;
}
}
}
I cannot get this to work, seems like whatever I do it never sorts correctly.
I am trying to sort in a descending order based on number of points.
Bryan_Bickell 2 5 +2
Brandon_Bolig 0 3 0
Dave_Bolland 4 2 -1
Sheldon_Brookbank 0 4 -1
Daniel_Carcillo 0 1 +3
The middle column is the amount of points.
I am using 4 arrays to store all of those values, how would I correctly utilize the array selection sort to get it to order in the right way?
I had tried all the answers below but none of them seemed to work, this is what i have so far
void sortArrays( string playerNames[], int goals[], int assists[], int rating[], int numPlayers )
{
int temp, imin;
int points[numPlayers];
for(int j = 0; j < numPlayers; j++)
{
points[j] = goals[j] + assists[j];
}
imin = points[0];
for(int i = 0; i < numPlayers; i++)
{
if (points[i] < imin)
{
imin = points[i];
}
}
for(int j = 1; j < numPlayers; j++)
{
if (points[j] > imin)
{
temp = points[j];
points[j] = points[j-1];
points[j-1] = temp;
}
}
}
it should go like this...
void selsort(int *a,int size)
{
int i,j,imin,temp;
//cnt++;
for(j=0;j<size;j++)
{
//cnt+=2;
imin=j;
for(i=j+1;i<size;i++)
{
//cnt+=2;
if(a[i]<a[imin])
{
//cnt++;
imin=i;
}
}
if(imin!=j)
{
//cnt+=3;
temp=a[j];
a[j]=a[imin];
a[imin]=temp;
}
}
}
You don't need 4 arrays to store those records if only the middle column is used for sorting, i.e, keys used for sorting the records. From my understanding, you are trying to sort those records of people based on the number of points with selection sort. Code should look like the following: assuming records is your array of records
void selectionSort(RECORD records[], int n) {
int i, j, minIndex, tmp;
for (i = 0; i < n - 1; i++) {
maxIndex = i;
for (j = i + 1; j < n; j++) //find the current max
{
if (records[j].point > records[minIndex].point)
{
//assume point is the number of point, middle column
minIndex = j;
}
}
//put current max point record at correct position
if (minIndex != i) {
tmp = records[i];
records[i] = records[minIndex];
records[minIndex] = tmp;
}
}
}
It will sort all your records in "descending order" as you want
how about store the data into a std::vector then sort it
int compare(int a, int b){
return (a>b);
}
void sort(std::vector<int> &data){
std::sort(data.begin(), data.end(), compare);
}
try to use vector as much possible, they have been heavy optimized for performance and better memory usage