in this program i am separating integers from a character array which consists of a space between them
#include<iostream>
#include<stdio.h>
#include<conio.h>
using namespace std;
int main()
{
int i = 0, t, l = 0, j, c, k, q = 0, num = 0;
char ch[10][10];
int ach[10][1];
cout << "enter the number of test cases";
cin >> t;
for (i = 0; i < t; i++)
{
fflush(stdin);
cin.getline(ch[i], 9);
}
for (i = 0; i < t; i++)
{
num = 0;
for (j = 0; ch[i][j] != '\0'; j++) //calculating length
{
l = j;
}
l = l + 1;
for (j = 0; j < l; j++)
{
if (ch[i][j] == ' ') //finding the space
c = j;
}
for (k = 0; k < c; k++) //taking first integer out of char array
{
q = ch[i][k] - 48; //parsing char to int
num = (num * 10) + q;
}
cout << "\n previous row element " << ach[0][1] << "\n"; //checking the value
ach[i][0] = num; // this statement is updating the previous row's last element of the array
cout << "\n previous row element " << ach[0][1] << "\n"; //checking the value
cout << ach[i][0];
num = 0;
q = 0;
for (k = c + 1; k < l; k++) //taking second element out of char array
{
q = ch[i][k] - 48; //parsing char to int
num = (num * 10) + q;
}
ach[i][1] = num;
cout << ach[i][1];
}
for (i = 0; i < t; i++)
{
cout << "\n" << ach[i][0] << "\t" << ach[i][1] << "\n"; //displaying the values
}
getch();
return 0;
}
I have marked the code that is malfunctioning , it is updating the previous row's last element. please help.
Oups your code is not really optimized and is mainly C with the exception of cin.getline. But your real problem is that with int ach[10][1], ach is a 2D array of size 10x1, so ach[i][1] may not be what you expect because you should define int ach[10][2] to safely use it. The rules for array indexes computing give &(ach[i][1]) == &ach[0][0] + i*1 + 1 so you are actually accessing ach[i+1][0] with a possible past end array access if i is 9.
Moreover, at first access, ach[0][1] is used without being first initialized.
So your ach definition should be:
int ach[10][2] = {0};
Related
I'm working on a KNN algorithm with 2D arrays. It worked great when I first had the nodes be simple X and Y coordinates, but when I changed it to 2D arrays and reworked some things, I run into a funny issue.
#include <iostream>
#include <math.h>
using namespace std;
//A node
struct Node
{
int groupValue;
int col = 16; //We only have to update these to reflect the bitmap dimensions
int row = 16;
int bitmap[16][16];
float distance = -1;
//distance is the distance this node is from another
//Overloading this operator to make swapping them with insertion sort easier
Node& operator =(const Node& n)
{
for(int a = 0; a < row; a++)
{
for(int b = 0; b < col; b++)
{
bitmap[a][b] = n.bitmap[a][b];
}
}
distance = n.distance;
groupValue = n.groupValue;
return *this;
}
};
void printNode(Node n)
{
for(int a = 0; a < 16; a++)
{
for(int b = 0; b < 16; b++)
cout << n.bitmap[a][b] << ".";
cout << endl;
}
}
struct Group
{
int frequency = 0;
int id;
};
void insertionSort(Node arr[], int n)
{
int i, key, j;
for (i = 1; i < n; i++)
{
key = arr[i].distance;
j = i - 1;
while (j >= 0 && arr[j].distance > key)
{
Node temp = arr[j+1];
arr[j + 1] = arr[j];
arr[j] = temp;
j = j - 1;
}
arr[j + 1].distance = key;
}
}
//Takes two bitmaps and find the distance between each pixel
//using the formula d=sqrt(sum((pixel_1-pixel_2)^2))
float bitmapDistance(Node n1, Node n2)
{
Node differences; //Node's bitmap data will be the differences
//squared of each pixel from n1 and n2.
float diff;
for(int a = 0; a < n1.row; a++)
{
for(int b = 0; b < n1.col; b++)
{
diff = n1.bitmap[a][b] - n2.bitmap[a][b];
differences.bitmap[a][b] = diff * diff; //Squared difference
}
}
//Now we need to sum up the squared differences that we stored earlier
float sum;
for(int a = 0; a < n1.row; a++)
{
for(int b = 0; b < n1.col; b++)
{
sum += differences.bitmap[a][b];
}
}
//Now just take the square root of the sum and return it
if(sum < 0.01) //To fix some weird rounding issues I added this. 0.01 is arbitrary.
return 0;
return sqrt(sum);
}
/*
*Classify the node using KNN algorithm
*Multiple groups can be used, and we count how many neighbors
*belong to each group.
*n is the total amount of nodes
*k is the number of nearby neighbors
*/
int classify(Node arr[], int n, int k, Node node)
{
//Two switches for sampling, recorded as binary (0-3)
Group g0;
g0.id = 0;
Group g1;
g1.id = 1;
Group g2;
g2.id = 2;
Group g3;
g3.id = 3;
Group groupFrequency[4] = {g0, g1, g2, g3};
//For each neighbor of the given node (node) we use the distance formula
//and set it's distance member variable to this measurement
for(int a = 0; a < n; a++)
{
arr[a].distance = bitmapDistance(node, arr[a]);
//cout << arr[a].distance << ","; //<===============PROBLEM AREA===============
}
cout << endl << "----------" << endl;
insertionSort(arr, n-1);
for(int a = 0; a < n; a++)
cout << arr[a].distance << ",";
cout << endl << "----------" << endl;
//Look at all the nearest neighbors and see which group they belong to
//Increase a counter for each group the neighbor belongs to
for(int i = 0; i < k; i++)
{
if(arr[i].groupValue == 0)
groupFrequency[0].frequency++;
else if(arr[i].groupValue == 1)
groupFrequency[1].frequency++;
else if(arr[i].groupValue == 2)
groupFrequency[2].frequency++;
else if(arr[i].groupValue == 3)
groupFrequency[3].frequency++;
}
cout << "Neighboring group frequencies:" << endl;
cout << "Group Zero: " << groupFrequency[0].frequency << endl;
cout << "Group One: " << groupFrequency[1].frequency << endl;
cout << "Group Two: " << groupFrequency[2].frequency << endl;
cout << "Group Three: " << groupFrequency[3].frequency << endl;
cout << "-------------------------------------------------" << endl;
//Now we just need to look at the most common frequency and classify our node
int highestFrequency = 0;
int groupNumber = -1; //If -1 is returned, something went wrong.
for(int a = 0; a < 4; a++)
{
if(groupFrequency[a].frequency >= highestFrequency)
{
highestFrequency = groupFrequency[a].frequency;
groupNumber = groupFrequency[a].id;
}
}
return groupNumber;
}
//This stuff is just setup for testing purposes. Could this be the issue's origin?
int main()
{
Node nodeArray[200];
for(int c = 0; c < 100; c++)
{
for(int a = 0; a < 16; a++)
{
for(int b = 0; b < 16; b++)
{
nodeArray[c].groupValue = 0;
nodeArray[c].bitmap[a][b] = rand()%10;
}
}
}
for(int c = 100; c < 200; c++)
{
for(int a = 0; a < 16; a++)
{
for(int b = 0; b < 16; b++)
{
nodeArray[c].groupValue = 1;
nodeArray[c].bitmap[a][b] = 50;//rand()%10+50;
}
}
}
Node testNode;
for(int a = 0; a < 16; a++)
{
for(int b = 0; b < 16; b++)
{
testNode.bitmap[a][b] = 50;//rand()%10+50;
}
}
int num = classify(nodeArray, 200, 189, testNode);
cout << "Test node has a group classification of: " << num << endl << endl;
printNode(testNode);
cout << endl << "last node in array:" << endl;
printNode(nodeArray[199]);
cout << endl << bitmapDistance(testNode, nodeArray[199]) << endl << "first node in array:" << endl;
printNode(nodeArray[0]);
cout << bitmapDistance(testNode, nodeArray[0]);
}
The problem specifically is on line 124, in the classify() function in the for loop
for(int a = 0; a < n; a++)
{
arr[a].distance = bitmapDistance(node, arr[a]);
//cout << arr[a].distance << ","; //<====PROBLEM AREA
}
This loop is responsible for calculating the distance each node is from the sample/test node. The "arr" array is then sorted a couple of lines later via insertion sort.
If I have the for loop print out the distance values, everything works perfectly fine. I can see that all the data is properly there.
However, if I comment it out, and only print the sorted data, everything is wrong (the data does not mess up if I comment out the print statements for the sorted data, strangely enough. It's just this one line that breaks everything).
I have attached images depicting the differences between the commented line (wrong) and the uncommented line (correct) running to better show what issues I'm dealing with.
Basically, the data will lose decimal precision, have seemingly random values, and any zero value will be non-existent if I comment out this specific line.
(I know the K value should be low, but I'm using high numbers for testing right now)
Some of the output when I don't comment out the line
Some of the output when I do comment out the line
As you can see, when I comment out the line, all the sorted distance values become garbage.
What can I do to fix this?
I have this code. and I have a problem with it. When I run it for these numbers "1,1,1,1,1" it answers me right but when I use these numbers "2,1,3,2,2" or any other numbers it answers me wrong. What is the problem?
#include <iostream>
using namespace std;
int main() {
int size = 5;
int array1[size];
int i, j, *p;
int sum = 0;
p = &array1[j];
for (int i = 0; i < size; i++) {
cout << "give next number";
cin >> array1[i];
cout << "\n";
}
cout << "the array is:"
<< "\n";
for (int j = 0; j < size; j++) {
cout << array1[j] << "\n";
sum = sum + *p;
}
cout << "the sum of array elements is: " << sum;
return 0;
}
So you have one problem
p = &array1[j];
What you are doing is taking the address of jth element of an array. In you case j is uninitialized which leads to UB since j might contain any variable.
To fix this you can initialize j to 0 (j = 0). Or to just get an address of first element in array you can do following:
p = array;
Than comes your loop, which is summit value at address of arr[j] which is UB as I stated above.
cout << "the array is:" << "\n";
for (j = 0; j < size; j++) {
cout << array1[j] << "\n";
sum = sum + *(p + j);
}
Your problem here was that you were adding array1[0] all the time. (That is if you initialized j to 0).
Other things to note is that you are re declaring i and j
int i, j, *p;
...
for (int i = 0; ...)
...
for (int j = 0; ...)
You could do just
for (i = 0; ...)
...
for (j = 0; ...)
to set already declared variables to 0.
Here is entire program:
#include <iostream>
int main() {
int size = 5;
int array1[size];
int i, j, *p;
int sum = 0;
// p = &array1[j]; // UB j not initialized but used
/* solution 1
j = 0;
p = &array1[j]
*/
// solution 2 which is same as solution 1
p = array1; // gets address of array[0]
for (i = 0; i < size; i++) { // no need for `int` in front of i
// i is already declared above
// my preference is to declare i here
// and remove declaration above
std::cout << "give next number";
std::cin >> array1[i];
std::cout << "\n";
}
std::cout << "the array is:"
<< "\n";
for (j = 0; j < size; j++) { // same as above
std::cout << array1[j] << "\n";
sum = sum + *(p + j);
}
std::cout << "the sum of array elements is: " << sum;
return 0;
}
input:
give next number5
give next number4
give next number3
give next number2
give next number1
output
the array is:
5
4
3
2
1
the sum of array elements is: 15
I am trying to figure out how to include a cout with a for loop that leaves off part of the cout on the last iteration. I want to have a multiplication sign (*) after each number (nFact) EXCEPT the last number in the loop.
Current output: 5*4*3*2*1*
Ideal output: 5*4*3*2*1
'''
for (unsigned int i = 0; i < n; i++)
{
nFact = nFact*(n-i);
cout << (n - i)<<"*";
}
'''
for (unsigned int i = 0; i < n; i++)
{
nFact = nFact*(n-i);
if(i!=n-1)
cout << (n - i)<<"*";
else cout << (n - i);
}
You might do:
const char* sep = "";
for (unsigned int i = 0; i < n; i++)
{
nFact *= n - i;
std::cout << sep << n - i;
sep = "*";
}
Demo
so I've got integers m and n in my program, once you input the values it should create an array with values from m to n (for example m = 1 and n = 10, it creates array q with values from 1 to 10). Then it looks in the array if there are any numbers that are equal to any two number summ that are squared (for example, in the array, number 5 is equal to 1 squared + 2 squared). The problem is when I try to input the first value it crashes, pretty sure the problem is in the function but can't seem to figure it out. Thanks
#include <iostream>
using namespace std;
int squared (int a, int b, int q[]){
while (a<=0 || b<=0){
cout <<"You can't input an integer that is 0 or below: ";
cin >>a;
cin >>b;
if (a>0 || b>0) break;
}
for (int p=0; p<b; p++){
for (int i=a ; i<b; i++){
q[p] = a;
}
}
for (int z=0; z<b; z++){
for (int x=0; x<b; x++){
for (int c=0; c<b; c++){
if (q[z] == (q[x] * q[x]) + (q[c] * q[c])){
int result= (q[x] * q[x]) + (q[c] * q[c]);
return result;
}
}
}
}
}
int main () {
int m,n;
int M[100];
cout <<"Input integers m un n: ";
cin >>m,n;
cout <<squared(m,n,M);
return 0;
}
Most likely it crashes because of this: cin >>m,n;, it should be cin >> m >> n;, else you use n uninitialized on the next line, thus getting undefined behaviour, e.g. crash.
What compiler are you using and with what flags, since this would trigger some warnings/errors at compile normally.
cin >> m, n; is incorrect which inputs only m which can be interpreted as:
(cin >> m), n; which means: cin, n; to correct it:
cin >> m >> n;
if(a > 0 || b > 0) break; is redundant because you check for this condition twice: once in while condition second inside while loop thus checking for the same condition is redundant because while breaks automatically if the condition succeeds (a or b is equal or smaller than 0).
you passed an array without passing its size, you are lucky if you set the first element 1 the any second value is equal to the size of array eg:
m = 1; n = 10; then the size is ten which is correct.
what about:
m = 7; n = 10; // now is size 10? it's only 3
to correct it pass the size eg:
m = 4; n = 8;
int size = 8 - 4;
cout << Squared(m, n, M, size);
also:
for (int p = 0; p < b; p++)
{
for (int i = a ; i < b; i++)
{
q[p] = a;
}
}
you are assigning the same value a to all elements of array and iterating doing the same thing in the nested-loop!!! it's likely to write:
int x = 0; x = 0;
so the condition of result inside squared will never succeed because the same value is never equal to its square. 4 = 4 * 4 is never reached
here is what you search for:
#include <iostream>
using namespace std;
// I only make squared search for the result not inputing m and n lik e in yours
int squared (int m, int n, int* M)
{
int result;
for(int i(0); i < n; i++)
for(int j(0); j < n; j++)
for(int k(0); k < n; k++)
if( (M[i] == ( (M[j] * M[j]) + (M[k] * M[k]) )) && j != k) // here to avoid comparing with the same index
{
cout << M[i] << " = (" << M[j] << "*" << M[j] << ") + (" << M[k] << "*" << M[k] << ")" << endl;
result = ( (M[j] * M[j]) + (M[k] * M[k]) );
cout << result << endl;
return result; // if success we return result
}
return -1; // otherwise we return -1 as a sign of error (no square yields in negative value)
}
int main ()
{
int n, m, size;
do
{
cout <<"m: ";
cin >> m;
cout << "n: ";
cin >> n;
if(n <= 0 || m <= 0)
cout <<"You can't input an integer that is 0 or below: ";
// also it's very important to check whether n is greater than m or not because if m == n or m > n then size will be negative and as you know no array has a negative nor 0 size
if(m >= n)
cout << "n must be greater than m!" << endl;
}while (m <= 0 || n <= 0 || m >= n);
size = n - m; // getting size of array assuming m can be any value
int* M = new int[n - m]; // allocating dynamic array
// inputting array as you asked
for(int i(0), j = m; i < size; i++, j++)
M[i] = j;
// checking the values of array elements
for(int i = 0; i < size; i++)
cout << M[i] << ", " ;
cout << endl;
// getting the result
cout << squared(m, n, M) << endl;
// cleaning
delete[] M;
return 0;
}
I am trying to form a heap using the following code ,But not sure why its not showing the correct output.
#include <iostream>
using namespace std;
int h[10], n;
void heapbottom()
{
int i, j;
for (i = n / 2; i >= 1; i--) {
int k = i;
int v = h[k];
bool heap = false;
while (!heap && 2 * k <= n) {
cout << "\n i value is :" << i;
j = 2 * k;
if (j < n) //there sre 2 children
{
if (h[j] < h[j + 1])
j++;
}
if (v >= h[j])
heap = true;
else {
h[k] = h[j];
k = j;
}
h[k] = v;
} //end of while
}
cout << "\n HEAP GENERATED \n";
for (int i = 0; i < n; i++)
cout << "\n ELEMENT IS:" << h[i];
}
int main()
{
cout << "\n Enter the maximum number of array elements \n";
cin >> n;
cout << "\n Enter the array to perform heap sort \n";
for (int i = 0; i < n; i++)
cin >> h[i];
heapbottom();
return 0;
}
If I change the outer loop to be
for (i = n / 2; i >= 0; i--)
I get 9 8 7 6 5 2 as a result, which I believe is a valid heap.