I am creating a sort selecting that puts the max number to the right. I think i have it mostly done and when i execute the code it works but it does not sort the first two numbers in order from smallest to largest.
When I compile I get 2,1,4,7,9,12,99
int n = 7;
int list[] = { 9, 2, 99, 4, 1, 12, 7};
int maxIndex = n - 1;
for (int i = 0; i < maxIndex-1; i++)
{
int maxNum = i;
for (int j = i+1; j < n; j++)
{
if (list[j] > list[maxNum])
{
maxNum = j;
}
int temp = list[j];
list[j] = list[maxNum];
list[maxNum] = temp;
}
}
Im not too sure if its the for function or it has to do with the swap that i have but i dont think its the swap or else the it wouldn't order the other numbers.
So there are a few problems. The first is that your loop limit is incorrect
for (int i = 0; i < maxIndex-1; i++)
should be
for (int i = 0; i < n-1; i++)
You can get rid of the maxIndex variable.
Second your swap is in the wrong place and you swap the wrong elements. You are supposed to swap the maximum value with the current value, so the swap should go after the j loop and not inside it. It's only after the j loop completes that you know what the maximum value is. Plus what you swap is list[i] (the current value) with list[maxNum] (the maximum value). Like this
int maxNum = i;
for (int j = i+1; j < n; j++)
{
if (list[j] > list[maxNum])
{
maxNum = j;
}
}
int temp = list[i];
list[i] = list[maxNum];
list[maxNum] = temp;
Incidentally I don't like the variable name maxNum because it is not a number it's an index. Maybe maxNumIndex would be a better name?
Related
gfg https://practice.geeksforgeeks.org/problems/subset-sum-problem2014/1
leetcode
https://leetcode.com/problems/partition-equal-subset-sum/
Problem:
Given an array arr[] of size N, check if it can be partitioned into two parts such that the sum of elements in both parts is the same.
Example
Input: N = 4
arr = {1, 5, 11, 5}
Output: YES
Explaination:
The two parts are {1, 5, 5} and {11}.
class Solution{
public:
static int equalPartition(int N, int arr[])
{
int sum = 0;
for (int i=0; i<N; i++)
sum += arr[i];
if (sum % 2 != 0)
return 0;
sum = sum/2;
int row = N+1;
int col = sum+1;
int dp[row][col];
for (int i=0; i<col; i++)
dp[0][i] = 0;
for (int i=0; i<row; i++)
dp[i][0] = 1;
for (int i=1; i<row; i++) {
for (int j=1; j<col; j++) {
if ( j< arr[i-1])
dp[i][j] = dp[i-1][j];
else{
if(j-arr[i-1] > 0){
dp[i][j] =max(dp[i-1][j], dp[i-1][j-arr[i-1]]);
}
else{
dp[i][j] = dp[i-1][j];
}
}
}
}
return dp[row-1][col-1];
}
};
So I signed up to portal out of curiosity to figure whats wrong. I was able to get correct answer with the following code. The code makes slight changes, mostly space compression.
As I suspected, the constraints for N (100) and sum of values in array (1e5) were very critical leading to segmentation fault.
Also instead of j-arr[i-1] > 0, it should be j-arr[i-1] >= 0.
Explanation of space compression:
We only need i-1 th state to compute values of current state i, so 2 arrays of size sum each are enough. I keep a reference curr to remember which of the 2 array is to be considered current and curr^1 would be the previous array. We can further optimize to only single array of size sum, but it is out of scope of the answer.
int equalPartition(int N, int arr[])
{
int sum = 0;
for (int i=0; i<N; i++)
sum += arr[i];
if (sum % 2 != 0)
return 0;
sum = sum/2;
int row = N+1;
int col = sum+1;
int dp[2][col]; // change 1
for (int i=0; i<col; i++)
dp[0][i] = 0;
// for (int i=1; i<row; i++)
// dp[i][0] = 1;
dp[0][0] = 1; // change 2, due to space compression don't need above
int curr = 1; // change 3
for (int i=1; i<row; i++, curr^=1) { // change 4
for (int j=1; j<col; j++) {
dp[curr][j] = dp[curr^1][j]; // change 5
if(j-arr[curr^1] >= 0) // change 6
dp[curr][j] =max(dp[curr][j], dp[curr^1][j-arr[i-1]]); // change 7
}
}
return dp[curr^1][col-1]; // change 8
}
};
I'm having a little problem with getting my head around this homework task. The task says: "Write a function called MoveSmallest that moves all the minimal integer elements at the start of the array. All the remaining items must stay at their places. (the array and its size are parameters)
Example: the array: 2, 3, 5, 1, 2, 3, 6, 4, 2, 1, 1 changes into 1, 1, 1, 2, 3, 5, 2, 3, 6, 4, 2
void MoveSmallest(int A[],int n)
{
int Min;
for(int i=0;i<n;i++)
{
if(i==0)
{
Min=A[i];
}
else if(A[i]<=Min)
{
Min=A[i];
}
}
So far I've only figured to check which one is the smallest element of the array. I don't have any ideas what to do next.
Once you have found the minimum value, all there is left to do is moving things around in order to have the minimum values at the beginning of the array.
You can do this by permuting the values until you have arrived to the "left" of the array (i.e index 0).
void MoveSmallest(int A[],int n)
{
int Min;
for(int i=0;i<n;i++)
{
if(i==0)
{
Min=A[i];
}
else if(A[i]<=Min)
{
Min=A[i];
}
}
for(int i = 0; i < n; i++)
{
if(A[i] == Min)
{
for(int j = i; j > 0; j--)
{
int tmp = A[j];
A[j] = A[j-1];
A[j-1] = tmp;
}
}
}
}
You could also use std::swap to do the permutation, instead of the temporary variable tmp.
Starting from the end of the array, keep track of how many minimal elements you have encountered. Then whenever you encounter a non-minimum element, move it to the right the number of minimal elements you have encountered so far:
void MoveSmallest(int A[], int n)
{
int min;
//Find min logic
//shift non-min elements and count min elements
int cnt = 0;
for (int i = n-1; i >=0; --i)
{
if (A[i] == min)
cnt++;
else
A[i+cnt] = A[i];
}
//Add min elements
for (int i = 0; i < cnt; ++i)
A[i] = min;
}
This will run in O(n) time and O(1) space.
Since your posts mention "basic C++" but not mention what is "basic", here is another solution. This is under the assumption that creating arrays for "work" purposes is considered "basic C++".
void MoveSmallest(int A[], int n)
{
// get the minimum value
int Min = A[0];
for (int i = 1; i < n; ++i)
{
if (A[i] < Min)
Min = A[i];
}
// get the count of the number of minimum values
int minCount = 0;
for (int i = 0; i < n; ++i)
{
if (A[i] == Min)
++minCount;
}
if (minCount > 0)
{
// create a work array and fill in the first
// minCount values with the minimum value
int *B = new int[n];
for (int i = 0; i < minCount; ++i)
B[i] = Min;
// now fill in the rest of the work array with the values
// in the A[] array that are not equal to Min
int current_pos = minCount;
for (int i = 0; i < n; ++i)
{
if (A[i] != Min)
B[current_pos++] = A[i];
}
// Now copy work array back to A array
for (int i = 0; i < n; ++i)
A[i] = B[i];
// get rid of work array
delete[] B;
}
}
Live Example
This runs in linear time O(n), as opposed to quadratic time O(n*n).
The disadvantage of course is that you need room for the work array, so the memory cost is linear O(n).
I have to write a code which sort digits in one entered number.
For example: input: 4713239
output: 1233479
It doesn't work properly when I enter repeating digits(like 33) when I have the last loop as FOR:
for(int j = 0; j < arr[i]; j++) // in this loop my output is: 123479.
When I change this loop from FOR to WHILE it works properly.
It means:
while(arr[i]) // and the number is sorted correctly (1233479)
True be told, I don't know what is the difference between these operations in this code.
Why FOR loop doesn't work properly? Could somebody explain me this?
I wrote a code:
int sort(int arg)
{
int var, score = 0;
int arr[10] = {0};
for(int i = 0; i < 10; i++)
{
var = arg % 10;
arr[var]++;
arg = arg / 10;
}
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < arr[i]; j++) //while(arr[i]) --> works correctly
{
score = score * 10 + i;
arr[i]--;
}
}
return score;
}
You modify both arr[i] and j, therefore the loop will end too fast when both are part of the comparison.
for(int j = 0; j < arr[i]; j++) // increase j, compare with arr[i]
{
score = score * 10 + i;
arr[i]--; // decrease arr[i]
}
That is my function:
int main() {
double data[100];
int num;
cout<<"num= ";
cin>>num;
for(int i = 1; i <= num; i++) {
cout<<i<<" element = ";
cin>>data[i];
}
Sort(data, num);
for (int i = 1; i <= num; i++) {
cout<<data[i]<<endl;
}
return 0;
}
void Sort(double data[], int n) {
int i,j,k;
double min;
for(i = 0; i < n-1; i++) {
k = i;
min = data[k];
for(j = i+1; j < n; j++)
if(data[j] < min) {
k = j;
min = data[k];
}
data[k] = data[i];
data[i] = min;
}
}
if I write for exp. three elements: 8,9,1 again cout 8,9,1?
for(int i = 1; i <= num; i++) { // WRONG
I think you mean:
for(int i = 0; i < num; i++) { // RIGHT
Arrays in C are 0-indexed remember.
Your sorting function is fine. The only problem is that you enter elements at positions 1 through n, inclusive, while you should use 0 through n-1, inclusive, in both loops of the main() function.
If you need to print numbers 1 through n, use
cout<<(i+1)<<" element = ";
You should get used of the 0 index begin in the for loop
for(int i = 0; i < N; ++i)
so fixing these two index errors will make your code run properly.
the reason is:
if you write data to data[] using 1 as the begining, your data array's first item will be a random number:
if you insert 3 elements, the array will be like this:
data[0] = ??? // maybe a very very big number
data[1] = 8
data[2] = 9
data[3] = 1
and in your Sort function, your index begins at 0 and ends before num, that means your code would only sort data[0], data[1], data[2].
if you use: num = 3, 3 2 1 as your input data for the origin code you could see that 3 and 2 is sorted
I guess your Sort code is googled from somewhere, please try to understand it.
Good online algorithm course: https://www.coursera.org/course/algs4partI
a very good algorithm online book: http://algs4.cs.princeton.edu/home/
btw, for(j = i+1; j < n; j++) in the Sort function would be better if it has { } braces.
what would be the c++ equivalent to this matlab code? I started it off but i'm not sure what value B would be, i think A is correct.
MATLAB
array = (-1:.001:1)';
A = max(find(array < 1.0e-2));
B = min(find(array > 1 - 1.0e-2));
C++ attempt
for(i = 0; i < array.size; i++){
if(array[i] < 1.0e-2){
k++
A = k;
}
if(array[i] > (1- 1.0e-2)){
//not sure what to do here
B = ?;
}
}
for(i = 0; i < array.size; i++){ // Would be faster if you reversed loop direction
if(array[i] < 1.0e-2)
A = i;
}
for(i = 0; i < array.size; i++) {
if(array[i] > 1-1.0e-2) {
B = i;
break;
}
}
For the second bit, I would do this instead inside the same loop:
if(array[array.size-i-1] > (1 - 1.0e-2)) B = array.size - i;
and initialize B to array.size before the loop.
Essentially, you are finding the element with the lowest index in the array which is also larger than 1 - 1.0e-2. If you start at the element with the highest index and then traverse the entire array and update each time you satisfy the criteria, you will end up with what you need. A similar logic applies for the first part, but you will need to set A = i+1 instead of incrementing k because there is no guarantee the array is sorted.
Basically the command A = max(find(array < 1.0e-2)); Is looking for the largest index of the array that is greater than 1.02e-2.
To see how this happens just break down the statement into parts:
array < 1.0e-2) returns a vector of logical indices.
find( ... ) converts the logical indices to numeric indices
max(...) returns the largest value from the list of numeric indices.
A C++ equivalent would look something like:
int A = -1;
int maxVal = 1.0e-2;
for (int i = array.length-1; i>=0; i--)
if (array[i] < maxVal){
A = i;
break;
}
To get B just setup another loop:
int B = -1;
int minVal = 1 - 1.0e-2;
for (int i=0; i<array.length; i++)
if (array[i] > minVal){
B = i;
break;
}