Array/Pointer confusion [closed] - c++

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Why does the following code print out "0 0 0 0 0 0 0 "? I was expecting "1 3 6 10 15 21 28 ".
#include <iostream>
using namespace std;
void PrefixSum(float * input, float * output, int n){
float sum = 0;
for (int i=0;i<n;i++){
float value = input[i];
sum += value;
output[n] = sum;
}
}
int main(int argc, const char * argv[])
{
float input[] = {1,2,3,4,5,6,7};
float output[] = {0,0,0,0,0,0,0};
PrefixSum(input, output, 7);
for (int i=0;i<7;i++){
cout << output[i] << " ";
}
return 0;
}

Change output[n] to output[i] instead, you're not writing to any index in the array since output[7] is out of bounds. i is your loop counter not n

change
output[n] = sum;
to
output[i] = sum;

As everyone's pointed out, you're using n as the index instead of i, so you never modify any value within the array.
Writing loops is error prone, many of us will have made mistakes over the years. It's better to reuse existing code.
You're calculating the partial_sum. Using the standard library you could code it like this:
#include <iostream>
#include <numeric>
int main(int argc, const char * argv[])
{
using std::partial_sum;
using std::cout;
const int SIZE = 7;
float input[SIZE] = {1,2,3,4,5,6,7};
float output[SIZE] = {0,0,0,0,0,0,0};
partial_sum(input, input+SIZE, output);
for (int i=0;i<SIZE;i++){
cout << output[i] << " ";
}
return 0;
}
We can eliminate the loop printing out the result too:
#include <algorithm>
#include <iterator>
//...
using std::copy;
using std::ostream_iterator;
copy(output, output+SIZE,
ostream_iterator<float>(cout, " "));
And, finally, if you don't need the intermediate results array, we can just put the results straight to the ostream instead:
partial_sum(input, input+SIZE,
ostream_iterator<float>(cout, " "));

output[n] = sum;, n is 7 is out of output array boundary and you write data to it every time. Note, this is also undefined behavior. You are accessing float value = input[i]; right in for loop, so I guess that's just a typo.
update
output[n] = sum;
to
output[i] = sum;

Replace the 'n' with the 'i' in your for-iteration in PrefixSum ;)

Related

Why is this one, pointless line of code the only thing that makes this function work? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm learning C++ and decided to make a bunch of small, short functions to practice. This following bit of code will give me an incorrect answer:
float pairwiseSum(float data[], int arraySize, int naive_sum_size=8) {
if (arraySize <= naive_sum_size) {
return naiveSum(data, arraySize);
} else {
int m = arraySize / 2;
return pairwiseSum(&data[0], m) + pairwiseSum(&data[m], arraySize-m);
}
}
naiveSum in this case just iterates through an array accumulates the sum and appears to work fine. If I have an array of 64 1s, it will tell me the sum is 288.
However, this version of the code works perfectly every time:
float pairwiseSum(float data[], int arraySize, int naive_sum_size=8) {
if (arraySize <= naive_sum_size) {
cout << "";
return naiveSum(data, arraySize);
} else {
int m = arraySize / 2;
return pairwiseSum(&data[0], m) + pairwiseSum(&data[m], arraySize-m);
}
}
I'm using Fedora 21 and compiling with g++ 4.9.2
Why does one function work, but the other one fail?
Edit: the complete program as it appears in my main.cpp file is below.
#include <iostream>
#include <stdlib.h>
using namespace std;
float naiveSum(float data[], int arraySize) {
float sum;
for (int i = 0; i < arraySize; i++)
sum += data[i];
return sum;
}
// Divide-and-conquer algorithm is a little faster than the
// Kahan Summation Algorithm, but also less accurate.
float pairwiseSum(float data[], int arraySize, int naive_sum_size=8) {
if (arraySize <= naive_sum_size) {
//cout << "";
return naiveSum(data, arraySize);
} else {
int m = arraySize / 2;
return pairwiseSum(&data[0], m) + pairwiseSum(&data[m], arraySize-m);
}
}
int main() {
const int SIZE = 64;
const int rndRange = 100;
// generate random array
srand(time(NULL));
float xs[SIZE];
for (int i=0; i<SIZE; i++)
// +1 prevents division by zero
//xs[i] = rand() % rndRange / (float)(rand() % rndRange + 1);
xs[i] = 1;
// Print kahan sum of random array
//cout << "Kahan Sum: " << kahanSum(xs, SIZE) << endl << endl;
cout << endl << pairwiseSum(xs, SIZE) << endl;
return 1;
}
Edit: yes, it was indeed a problem with sum not being intialized. Thanks for your help.
sum is not initialized in naiveSum. The rest is just undefined behavior (caused by indeterminate value in sum) manifesting itself differently with or without that irrelevant cout << "" line.
There are many different ways cout << "" can cause that indeterminate initial value of sum to end up being zero and thus create an appearance of naiveSum working properly.

c++ Replacing character with a number [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have this code. What i wanted to do is to replace every letter from every char with indicated number. Like for A is 10, and so on until J, 19. My code works well if i have only one letter in my char array, but if i have more after another it copies useless things. I think that something is wrong with strncat.
#include<conio.h>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char litera[11]={"ABCDEFGHIJ"};
char cifra[11]={"0123456789"};
char rezultat[256]={0};
int n;cin>>n;cin.get();
for(int i=0;i<n;i++)
{
char x[256];
cin.get(x,256);cin.get();
int k=strlen(x);
for(int j=0;j<k;j++)
{
int p = strchr(litera,x[j])-litera;
if(p>=0 )
{
strncat(rezultat, x,j);
// my p is the indicator for letter and number
strcat(rezultat,"1");
// I'm copying an 1 there because i have numbers
// between 10-19 and in my int array i have only
// the second cipher
strcpy(x,x+j);
rezultat[strlen(rezultat)]=cifra[p];
}
}
cout<<rezultat<<endl;
memset(rezultat,0,sizeof(rezultat));
}
getch();
return 0;
}
Input: 07B, 1AA, C8A
Output: 0711, 11010, 12810
My output:
0711
110AA1
12C810
If you guys can tell me where the problem is, you'll help me a lot, every suggestion is well received, even if is not about this problem. Thanks!
If it is allowed to use vector and string then you can try the following (I tested it and it works.) The input here should be line by line(each line is a new string to be converted) but of course you may modify this part based on your input format:
Include those:
#include <vector>
#include <iostream>
#include <string>
//#include <conio.h>
//#include <cstring>
//using namespace std;
int main()
{
int n;
std::cin >> n;
while (n--)
{
string input;
std::cin >> input;
vector<char> resultat;
for (int i = 0; i < input.size(); i++)
{
if (input.at(i) >= 'A' && input.at(i) <= 'J') // it is a letter between A and J
{
int number = input.at(i) - 'A' + 10;
char ones = (char)(((int)'0') + (number % 10));
char tens = (char)(((int)'0') + (number / 10));
resultat.push_back(tens);
resultat.push_back(ones);
}
else
resultat.push_back(input.at(i));
}
for (int i = 0; i < resultat.size(); i++)
{
std::cout << resultat[i];
}
std::cout << endl;
}
}
if string is not allowed just use your character array. There seems to be nothing wrong in your input format.
If vector is not allowed either, then you may create a char pointer the initialize it based on the final size.
For example:
int newSize=0;
for (int i = 0; i < input.size(); i++)
{
if (input.at(i) >= 'A' && input.at(i) <= 'J')
newSize+=2;
else
newSize++;
}
char* resultat = new char[newSize];
...
Then just fill the resultat.
Hope that helps!
Do you have to do it with your multiple arrays? You could perform a switch-case for only specified inputs. Since you are replacing letters A-J with numbers 10-19, you can easily implement this in switch case. You can also check for incorrect input as well.
If you have to use arrays, first question is why is you numerical array the single digits? Is this is constraint? Cant you use :
char cifra[11]={"10","11","12","13","14","15","16","17","18","19"};
for the array instead, that way you can refer to the array index and replace it using the index? This way, you can compliment the arrays by just using index referencing to replace the output based on the index, such as A is index 1 for alphabetical array which refers to index 1 of the numerical array which is "10" so you just print the array index value to a variable and output it.

weird things using std::vector [duplicate]

This question already has answers here:
binary_search in c++ unexpected behaviour
(4 answers)
Closed 9 years ago.
I wrote a simple code to insert 2,4,8,16,32,3,9,27,5,6,7 into a vector object.
After insert these numbers, I check with std::binary_search for 8, but weirdly it returns 0.
Here is the code. I do not know why. Could someone help me?
Thanks a lot!
#include <iostream>
#include <math.h>
#include <vector>
#include <algorithm>
using namespace std;
void printVector(vector<int>const & p) {
for (int i = 0; i < p.size(); i++)
cout << p[i] << ' ';
cout << endl;
}
int main() {
const int max = 100;
int num;
vector<int> base;
for (int i = 2; i <= 7; i++) {
int expo = log(max) / log(i);
num = 1;
for (int iexp = 1; iexp < expo; iexp++) {
num *= i;
if (!binary_search(base.begin(), base.end(), num)) { // If the number is not in the vector
base.push_back(num); // Insert the number
printVector(base); // Reprint the vector
cout << endl;
}
}
}
cout << binary_search(base.begin(), base.end(), 8) << endl;
printVector(base);
return 0;
}
The sequence must be sorted for std::binary_search. Behavior is undefined if the sequence is not sorted.
You can use std::sort to sort it first, or, depending on what kind of performance you need, you can use std::find to do a linear search.
Binary search requires the vector be sorted. If you insert values in random order the results of the binary search will be unpredictable.
std::binary_search only works on sorted sequence. You need to sort the vector first.

C and C++ difference behavior [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have created two template project in Eclipse with CDT plugin(one is C project, another C++), and have compiled two very similar projects(as for me) but I get absolutely different console outputs. Why this outputs so different?
C code:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int numbers[5];
int * p;
p = numbers; *p = 10;
p++; *p = 20;
p = &numbers[2]; *p = 30;
p = numbers + 3; *p = 40;
p = numbers; *(p+4) = 50;
int n;
for (n=0; n<5; n++)
printf("%c ",numbers[n]);
return EXIT_SUCCESS;
}
output
some garbage
C++ code:
#include <iostream>
using namespace std;
int main() {
int numbers[5];
int * p;
p = numbers; *p = 10;
p++; *p = 20;
p = &numbers[2]; *p = 30;
p = numbers + 3; *p = 40;
p = numbers; *(p+4) = 50;
for (int n=0; n<5; n++)
cout << numbers[n] << " ";
return 0;
}
output
10, 20, 30, 40, 50
You are printing int as char in C.
Change
printf("%c ",numbers[n]);
to
printf("%d ",numbers[n]);
You're trying to output the numbers as characters, causing your odd output.
The code worked fine for me as this.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int numbers[5];
int * p;
p = numbers; *p = 10;
p++; *p = 20;
p = &numbers[2]; *p = 30;
p = numbers + 3; *p = 40;
p = numbers; *(p+4) = 50;
int n;
for (n=0; n<5; n++)
printf("%d ",numbers[n]);
return EXIT_SUCCESS;
}
Note the %d, rather than %c
You print the ASCII value of the integers. Try
printf("%i", numbers[n])
instead of
printf("%c", numbers[n])
You need %d to print integer and %c to print char in C
http://www.cplusplus.com/reference/cstdio/printf/
Look at your below statement
printf("%c ",numbers[n]);
You are using %c to print int, which is wrong.
To be specific printf has been borrowed from C and has some limitations. The most common mentioned limitation of printf is type safety, as it relies on the programmer to correctly match the format string with the arguments. The second limitation that comes again from the varargs environment is that you cannot extend the behavior with user defined types. The printf knows how to print a set of types, and that's all that you will get out of it. Still, it for the few things that it can be used for, it is faster and simpler to format strings with printf than with c++ streams.

Constructing Identity Matrix [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have tried to solve an algorithm problem, I'm newbie and I'm trying to practice a lot in programming problems. So I wanted to construct an Identity matrix n*n. I came up with a stupid solution, that worked for a 4*4 matrix, but it didn't work with 5*5. I know that its weird solution and the solution to the problem is really easy when I looked at it. I need to know what did I do wrong so that I can learn, and is my solution is really stupid and I will be better in the future after working much in solving those kind of problems ?
#include <iostream>
#include <vector>
#include <sstream>
#include <iomanip> // for setw, setfill
using namespace std;
int binary(int number);
int main()
{
vector<vector<int> > matrix;
cout<<"Please enter the size of the identity matrix"<<endl;
int n;
cin>>n;
matrix.resize(n);
for (int i=0; i<n;i++)
{
matrix[i].resize(n);
}
int steps = 1<<n-1;
int bin = binary(steps);
ostringstream binString;
binString <<bin;
if(binString.str().size()<n)
{
std::string dest = binString.str();
int nPaddings = n-binString.str().size();
if (nPaddings==0) nPaddings=1;
dest = std::string( nPaddings, '0').append( binString.str());
binString.str("");
binString<<dest;
}
for (int col = 0; col<n; col++)
{
if(col>=1)
{
steps= (int)steps/2;
int bin = binary(steps);
binString.str("");
binString << bin;
if(binString.str().size()<n)
{
std::string dest = binString.str();
int nPaddings = n-steps;
if (nPaddings==0) nPaddings=1;
dest = std::string( nPaddings, '0').append( binString.str());
binString.str("");
binString<<dest;
}
}
for (int row=0; row<n; row++)
{
matrix[col][row] =binString.str().at(row)-'0';
}
}
return 0;
}
int binary(int number) {
long rem,i=1,sum=0;
do
{
rem=number%2;
sum=sum + (i*rem);
number=number/2;
i=i*10;
}while(number>0);
return sum;
}
There is a much simpler way to do it.
First, you should allocate your matrix with the specified size. Then, you know that only the diagonal is 1s:
vector<vector<int> > matrix;
int n;
cout << "Please enter the size of the identity matrix" << endl;
cin >> n;
// Initialize the matrix as a n x n array of 0.
matrix = vector<vector<int> >(n, vector<int>(n,0));
// Set the diagonal to be 1s
for(unsigned int t = 0; t < n; t++)
matrix[t][t] = 1;
You can see a live example here.
Edit:
Your error comes from this line:
int nPaddings = n-steps;
In fact, you're not using the size of dest to compute the padding, which is not correct. See here, I added some debug printfs to see the state of the variables. You can see that nPaddings == -3, hence the errors.
The idea you have:
for each column
get the representation of the column as a string
set the i-th value of the column as the i-th character of the string
So, here is a simpler program using your idea. Separating the code in several functions helps a lot. Also, std::ostringstream and std::string is just pure overkill here.
#include <iostream>
#include <vector>
#include <iomanip> // for setw, setfill
using namespace std;
std::string binStr(unsigned int exponent, unsigned int size);
int main()
{
vector<vector<int> > matrix;
cout<<"Please enter the size of the identity matrix"<<endl;
int n;
cin>>n;
// Initialize the matrix
matrix.resize(n);
for (int i=0; i<n;i++)
matrix[i].resize(n);
// Fill the matrix
for (int col = 0; col<n; col++)
{
std::string bin = binStr(n-col,n);
for (int row=0; row<n; row++)
matrix[col][row] = bin[row]-'0';
}
// Print the matrix and return
for(unsigned int y = 0; y < n; y++)
{
for(unsigned int x = 0; x < n; x++)
cout << "\t" << matrix[y][x];
cout << "\n";
}
return 0;
}
std::string binStr(unsigned int exponent, unsigned int size)
{
// You do not need a string stream (which is like using a bazooka to kill a fly...)
// Instead, just create a string of the required length
// 'str' will contain the binary representation of 2^exponent
std::string str(size,'0');
if(exponent <= size && exponent > 0)
str[size - exponent] = '1';
return str;
}
You can see it in action here.
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int> > make_idty_matrix( int n )
{
vector<vector<int> > idty( n, vector<int>( n, 0 ));
for( int i = 0; i < n; ++i )
idty[i][i] = 1;
return idty;
}
int main()
{
vector<vector<int> > matrix = make_idty_matrix( 5 );
// your code here
// ...
return 0;
}