Two different strings get same value

My program is supposed to
1. read how many numbers will be given
2. read thix x numbers
3. give us sum of all numbers
Program has to tell the result in shortest way possible. The value given might be f.e +1,000000000 (even though it is simply "1") , etc. and so my program works like this:
it reads the values, if the value is below 0 then it adds it to sSubstraction, else to sSum. At the end it`s supposed to sum them.

However there is a problem in a "dodawanie" procedure (at least this is where my searching got me)--> i don`t know why but f.e if I input the number 6, both sSum and sSubstraction get this value (only sSum shoud).
As the length of the number might be 100 before "," and 100 after,and it can have "+" or "-" at the begining, I`ve decided to make it a string value. the 100 is the number before ",", and 101 is the "theoretical" adress of ",". iPrze is the position of "," in the number we get from user.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <iostream>
#include <conio.h>
#include <string>


using namespace std;
int iIle;
string iTab[99];
string sSum;
string sSubstraction;


void dodawanie(int nr)
{
 	 int iDlug;
	 int iPrze=0;
	 iDlug=iTab[nr].size();
	 int i;
	 if(iTab[nr][0]=='+')
	 iTab[nr][0]=='0';
	 while (iTab[nr][iPrze]!=',' && iPrze<iDlug)
	 iPrze++;
	 if(iTab[nr][0]!='-'){
	 for(i=iDlug-iPrze-1;i>0;i--)
	 {
	  		 if(iTab[nr][0]=='+')
	  		 iTab[nr][0]=='0';
  			 sSum[101+i]=sSum[101+i]+iTab[nr][iPrze+i]-48;
	  		 if(sSum[101+i]>57)
	  		{
					sSum[101+i]=sSum[101+i]-10;
					if(i==1)
					sSum[100]++;
					else
					sSum[100+i]++; 					
	         }
	 }   
	 for(i=0;i<iPrze;i++)
	 {
	  		sSum[100-i]=sSum[100-i]+iTab[nr][iPrze-i-1]-48;
			if(sSum[100-i]>57)
			{
					sSum[100-i]=sSum[100-i]-10;
					sSum[99-i]++; 				   
			} 				  
					
     }						  
	 }else{
	 iTab[nr][0]='0';
	 for(i=iDlug-iPrze-1;i>0;i--)
	 {
	  		sSubstraction[101+i]=sSubstraction[101+i]+iTab[nr][iPrze+i]-48;
	  		if(sSubstraction[101+i]>57)
	  		{
					sSubstraction[101+i]=sSubstraction[101+i]-10;
					if(i==1)
					sSubstraction[100]++;
					else
					sSubstraction[100+i]++;
					
	 }   
	 for(i=0;i<iPrze;i++)
	 {
	  		sSubstraction[100-i]=sSubstraction[100-i]+iTab[nr][iPrze-i-1]-48;
			if(sSubstraction[100-i]>57)
			{
					sSubstraction[100-i]=sSubstraction[100-i]-10;
					sSubstraction[99-i]++; 				   
			}
     }			
	 }
}


void wynik()
{
 	 int i;
	 if (sSum>sSubstraction)
	 {
	 for(i=100;i>0;i--)
	 {
	  		sSum[101+i]=sSum[101+i]-sSubstraction[101+i]+48;
  		    if(sSum[101+i]<48)
  		    {
				sSum[101+i]=sSum[101+i]-10;
				if(i==1)
				sSum[100]--;
				else
				sSum[100+i]--;				
	         }
	 }   
	 for(i=0;i<100;i++)
	 {
	  			sSum[100-i]=sSum[100-i]-sSubstraction[100-i]+48;
				if(sSum[100-i]<48)
				{
					sSum[100-i]=sSum[100-i]+10;
					sSum[99-i]--; 				   
				 } 
		}
     } else
	 {
	 sSum[0]='-';		
	 for(i=100;i>0;i--)
	 {
	  			sSum[101+i]=sSubstraction[101+i]-sSum[101+i]+48;
	  			if(sSum[101+i]<48)
	  			{
					sSum[101+i]=sSum[101+i]-10;
					if(i==1)
					sSubstraction[100]--;
					else
					sSubstraction[100+i]--;					
	            }
	 }   
	 for(i=1;i<100;i++)
	 {
	  				sSum[100-i]=sSubstraction[100-i]-sSum[100-i]+48;
					if(sSum[100-i]<48)
					{
					sSum[100-i]=sSum[100-i]+10;
					sSubstraction[99-i]--; 				   
				    } 	  
		}
		}
		if (sSum[0]=='-')
		cout<<"-";
		i=1;
		while(i<100 && sSum[i]!=0)
		i++;
		for(;i<100;i++)
		cout<<sSum[i];
		cout<<sSum[100];
		i=201;
		while(i>101 && sSum[i]!=0)
		i--;
		if(i!=101)
		{
		 		  cout<<",";
  				  for(int j=101;j<=i;j++)
				  cout<<sSum[i];
        }
}
 	 

int main()
{
 	cin>>iIle;
 	for (int i=0;i<iIle;i++)
 	cin>>iTab[i];
    for (int i=0;i<202;i++)
	{
	 	sSum[i]='0';
	 	sSubstraction[i]='0';
		}
 	for(int i=0;i<iIle;i++)
	dodawanie(i);
	wynik();
 	getche();
	return 0;
}
Last edited on
You have written an 171-line-program to calculate the sum of a variable amount of numbers? Wy do you need strings? What's wrong with a simple for-loop?
Sorry that I dont answer your question, but if your assigment is just those three points you mentioned, you're on the wrong way...
Well, because the numbers might be too big for a normal real/integer
That's a good reason. But I think this is a school-assigment. So unless your teacher explicitly told you that the program should be able to handle bigger numbers to, I would stick to integers.
And there are other, easier solutions when dealing with big numbers. There are special librarys designed to handle them. If you're familair with OOP, you could write an own simple class that holds an array for all digits.
well (theoreticaly) I know.
This is not a school assigment, but an exercise from a certain page, exactly as I`ve said it has to read numbers made out of (maximum) 100 digits before coma and 100 after + sign
How about someting like this:
1
2
3
4
5
6
7
8
class BigNumbers
{
public:
...//overload operators or create your own functions
private:
int DigitsFor[100];//digits for comma
int DigitsAfter[100];//digits after comma
};


It would be quit easy to create a class with all the operators, or with your own functions.
I know there're librarys wich do that for you, but I'm not familiair with them. I dont know or there is a standardlibrary to deal with big numbers. Maybe give it a try on google?

But even if you create your own library I think it would be less work then using strings.
Well then, what about reading the numbers? This task is being checked automatically, after each number enter is pressed. Also it cannot use not primary c++ libraries (or something like this, f.e. conio.h is not there, but string and algorithm is)
Oke, this is how I would do it:

If we would only have integers, the following code would fit:
1
2
3
4
5
6
7
8
9
10
11
12
    int input;
    int result=0;
    cout<<"How many numbers would you like to enter?\n";
    cin>>input;
    for (int i=0;i<input;i++)
    {
        int temp;
        cout<<"Enter next number: ";
        cin>>temp;
        result+=temp;
    }
    cout<<"The sum is: "<<result<<".\n\n";


Now, lets see what operations we do with the integers. First, we store a value in them: cin>>temp;. Then we add that value to result:result+=temp;. Finally, we print the result: cout<<...<<result<<...;.
I think in this case it's easier to create function then to overload operators. So we would get someting similair to the following:
1
2
3
4
5
6
7
8
9
10
11
class BigNumbers
{
  public:
    BigNumbers();
    void store(string input);
    void add(BigNumbers number);
    void print();
  private:
    int DigitsFor[100];//digits for comma
    int DigitsAfter[100];//digits after comma
};


First a constructor, where you can give all elements of the two arrays the value 0.
Then the function store(). Because we cant use a number-type variable to hold such a big number (that was the orginal problem) the parameter-type is string. In this function, I would seperate the string in two substrings: before and after the comma. Then, you can use the memberfunction substr() to get each element of the string, stringstream to turn it into a number (0-9) and then store them into the elements of the two arrays using a simple for-loop.
The function add() is easier: take the sum of two equal elements, then use %10 and /10 to make sure no elements are greater as 9.
Finally, the function print() is really easy to write. Check when the first and last 'real' number is (other as 0) and then print.

Good luck, Scipio
Worth adding that cin >> number; should be replaced with getline(); - http://www.cplusplus.com/forum/articles/6046/
Firstly, thank you for your help ;]
Well then, i`ve rewritten code, trying to do as you suggested. I couldn`t do it exactly as you proposed because you`ve forgotten about the numbers below zero, but here is the modified version.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <iostream>
#include <conio.h>
#include <string>
#include <sstream>
using namespace std;
		
class BigNumbers{
	public:
		
		BigNumbers();
		string sValue;
		void store();
		short extract1(short);
		short extract2(short);
	private:
		short sign;
		short digitsfor[99];
		short digitsafter[99];
		
};
	BigNumbers 	tTab[100];
	short 		sN;
	short		result[199];
	
BigNumbers::BigNumbers(){
	for (int i=0;i<99;i++){
		digitsfor[i]=0;
		digitsafter[i]=0;
	}
	sign=1;
};

void BigNumbers::store(){
	int i=0;
	int iL=sValue.size();
	if (sValue[0]=='-'){
		sign=-1;
		sValue[0]='0';
		i++;
	}
	
	while(sValue[i]!=',' && i<iL)
		i++;
	short o=99;
	short j=i-1;
	while(j>=0){
		digitsfor[o]=(sValue[j]-'0')*sign;
		o--;j--;
	}
	o=0;
	j=i+1;
	while(j<iL){
		digitsafter[o]=(sValue[j]-'0')*sign;
		o++;j++;
	}
}

short BigNumbers::extract2(short s){
	return digitsfor[s];
}

short BigNumbers::extract1(short s){
	return digitsafter[s];
}	
	
void add(){
	for(short j=199;j>99;j--){	
		for(short i=0;i<sN;i++)
		result[j]+=tTab[i].extract1(j-100);
		result[j-1]+=result[j]/10;
		result[j]%=10;
		
	}		
	for(short j=99;j>0;j--){
		for(short i=0;i<sN;i++)
		result[j]+=tTab[i].extract2(j);
		result[j-1]+=result[j]/10;
		result[j]%=10;
		
	}
}
(... i`ve ommitted some functions, as they`re probably not important...)
int main()
{	
	for(int i=0;i<199;i++)
	result[i]=0;
	cin>>sN;
	for(short i=0;i<sN;i++){
		cin>>tTab[i].sValue;
		tTab[i].store();
	}
	add();
	transform();
	//writeres();

	getche();
	return 0;
}


line 47 is the most troublesome for me now. why the hell is this line giving value to BOTH digitsfor and digitsafter?
secondly, i tried to get strings-values with getline(); but I don`t know why it has always worked 1 time less then normal (f.e if sN was 1 it didn`t ask for values, if it was 3 it asked 2 times). But more importantly what`s wrong with the first one? i`m using dev-c++
Last edited on
Line 47 isn't giving both digitsfor and digitsafter values: the problem is in your variable j. First you're going up (j++) and then down (j--) so all values for digitsfor and digitsafter will be the same but the swapt (eg 321,123).

Your second question is hard to answer but easy to solve: the problem is that using both getline and cin (line 87) gives problems. You shouldn't use cin>> at line 87 anyway, since sN a short integer and entering characters into an integer will make the program crash. See Zaita's article about getline:http://www.cplusplus.com/forum/articles/6046/.

Furthermore, I have a few suggestions:
- make result from type BigNumber and add the memberfunction add() to that class. Now you've created a class to handle big numbers, and when using a bignumber (result) you're using other solutions.
- I think it's easier to use a memberfunction print() instead of extract(), aldo it wouldn't make much difference
- make sValue a parameter from store(): always try to hold membervariables in private.
- use the following sequence for digitsfor: 5 4 3 2 1 0, and for digitsafter: 0 1 2 3 4 5. You'll find this usefull when printing and storing the values.
- about storing the value: you should first take the first element of the string and see or it's a '-'. Maybe it's smart to create another membervariable from type bool to see or the value is positive or negative. Then split the string into a string for ''." and after. You can use string.find(".") to do this. When you figured that out, you can use two for-loops to initialize the values.
- in main(), add() should be inside the for-loop I think

There may be some other problems I missed, but first try to get those things straight.
Well as I didn`t have enough time to use all your advices, my program still has some space left for improvement. Anyway, thanks to everyone who tried to help me, and so :P This is the final product of my struggles, working but as i`ve said previously - it`s checked automatically so I didn`t put any anti-idiots mechanisms ;P In my language you write f.e 1,25 not 1.25 so take this into consideration if you would like to use this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <iostream>
#include <conio.h>
#include <string>
using namespace std;

class BigNumbers{
	public:

		BigNumbers();
		string sValue;
		void store();
		short extract1(short);
		short extract2(short);
	private:
		short sign;
		short digitsfor[100];
		short digitsafter[100];

};
	BigNumbers 	tTab[100];
	short 		sN;
	short		result[200];

BigNumbers::BigNumbers(){
	for (int i=0;i<100;i++){
		digitsfor[i]=0;
		digitsafter[i]=0;
	}
	sign=1;
};

void BigNumbers::store(){
	int i=0;
	int iL=sValue.size();
	if (sValue[0]=='-'){
		sign=-1;
		sValue[0]='0';
		i++;
	} else if (sValue[0]=='+'){
	    sValue[0]='0';
	    i++;
	}

	i=sValue.find(',');
	if(i==string::npos)
	i=iL;
	short o=99;
	short j=i-1;
	while(j>=0){
		digitsfor[o]=(sValue[j]-'0')*sign;
		o--;j--;
	}
	o=0;
	j=i+1;
	while(j<iL){
		digitsafter[o]=(sValue[j]-'0')*sign;
		o++;j++;
	}
}

short BigNumbers::extract2(short s){
	return digitsfor[s];
}

short BigNumbers::extract1(short s){
	return digitsafter[s];
}

void add(){
	for(short j=199;j>99;j--){
		for(short i=0;i<sN;i++)
		result[j]+=tTab[i].extract1(j-100);
		result[j-1]+=result[j]/10;
		result[j]%=10;

	}
	for(short j=99;j>0;j--){
		for(short i=0;i<sN;i++)
		result[j]+=tTab[i].extract2(j);
		result[j-1]+=result[j]/10;
		result[j]%=10;

	}
}

void transform(){
	short i=0;
	while(result[i]==0 && i<199)
	i++;
	if (result[i]>0){
		for(short j=199;j>i;j--){
			if(result[j]<0){
				result[j-1]+=(result[j]/10)-1;
				result[j]=(10+result[j])%10;
			}
		}
	}else{
		for(short j=199;j>i;j--){
			if(result[j]>0){
			    result[j-1]+=(result[j]/10)-1;
				result[j]=(-10+result[j])%10;
			}
		}
	}


}

void writeres(){
	short i=0;
	while(result[i]==0 && i<99){
		i++;
	}
	cout<<result[i];
	for(i++;i<=99;i++){
		if(result[i]<0)
		cout<<result[i]*-1;
		else
		cout<<result[i];
		}
	i=199;
	while(result[i]==0 && i>99)
		i--;
	if(i>99){
		cout<<",";
		for(short j=100;j<=i;j++){
			if(result[j]<0)
			cout<<result[j]*-1;
			else
			cout<<result[j];
		}
	}



}
int main(){
	for(int i=0;i<199;i++)
	result[i]=0;
	cin>>sN;
	for(short i=0;i<sN;i++){
		cin>>tTab[i].sValue;
		tTab[i].store();
	}
	add();
	transform();
	writeres();

	getche();
	return 0;
}
Last edited on
Topic archived. No new replies allowed.