splitting a string of integers...

Pages: 12
In the to_string() function, I am trying to pull the integers out of the vector, then convert the integers back to string and concatenate them back to its original form. Example would be: s="12345678910" is the inputted string. The string will be broken up into blocks of eight, starting from the end and then converted into integers to store in an integer vector "vec". So, vec[0]=910, vec[1]=12345678. After that, I want to pull the integers back out so vec_integers=12345678910, and then convert that into a string, stringout="12345678910".

I have tried different things but am having trouble making this work...Any ideas?

Here is what I have right now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::string Big_Nat::to_string()
{
	std::stringstream ss;
	std::string stringout="\0";
	std::string x[num_strings];
	for(int j=0;j<num_strings;j++)
	{
		int vec_string = vec.back();
		vec.pop_back();
		ss << vec_string; 
		x[j] = ss.str();
		stringout += x[j];	
	}
	return stringout;
};
oops, i meant vec[0]=45678910 and vec[1]=123...
closed account (D80DSL3A)
In your post you state that stringout = "12345678910" is the desired output, but this IS identical to the string (s) entered by the user. So cout << s << endl; should do it.

If you are looking to output stringout = "vec[0]" + "vec[1]" = "45678910123", then perhaps this would work:
1
2
3
4
5
for(int j=0; j< Nsubs; j++)// the full 8 digit numbers printed back-to-back
    cout << vec[j];

if( lastLen )// one more to go, the "remainder" value
    cout << vec[Nsubs] << endl;


Is this right?
That is what I need the program to do, but not exactly what needs to be done. big_nat.cpp is an implementation file. Big_Nat_test.cpp file wil be the one outputting the original string to the console screen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "big_nat.h"
#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s;
	cout << "Give x : "; getline(cin,s,'\n');
	Big_Nat x(s);
	cout << "---> x : " << x.to_string() << endl;
	cout << "Give y : "; getline(cin,s,'\n');
	Big_Nat y(s);
	cout << "---> y : " << y.to_string() << endl;
//	Big_Nat z = x + y;
//	cout << " x + y : " << z.to_string() << endl;
	return 0;
}


Since the cout is in the test file, the implementation file, I assume, would have to return a string. That's why I am trying to convert the integers back to a string. And you are correct, I can possibly use the orignal string and send it back, but this is part of a larger program and I need this function to work as intended, which is taking a vector of integers and converting them back to a string in its orginal form. The reason is that I will need to add two large numbers, z = x + y, and then output it to the screen. Although I can output x and y by re-using what the user had entered as strings, y will not be user inputted. I hope that makes sense. And I also hope you can help me on this. It's making me go crazy!
Last edited on
closed account (D80DSL3A)
I think I get the big picture now. The goal is to add two bigNums z = x + y and display the result z, after converting it back to a string. I will get back on this.

I will be using dynamic arrays instead of vectors here.
For now, check out this structure, which contains all the elements needed for each BigNum object.

1
2
3
4
5
6
7
8
9
10
11
struct BigNumData
{
	string str;// string representation of BigNum
	int len;// total # of digits in BigNum
	int lastLen;// length of last < 8 digit # (the leftover most significant digits)
	int Nsubs;// # of 8 digit #'s
	int* pInt;// pointer to array of integers, which will be used to dynamically allocate	
			  // Nsubs + 2 integers for the array. This should make the array large enough
			  // for worst case. z may be one digit longer than the longest of x or y
			  // due to carrying of a digit following the summation of x and y
};


We will be working with 3 BigNumData objects. Namely:
BigNumData x, y, z;
closed account (D80DSL3A)
OK - forget that structure. I'm going with a class implementation, similar to yours.
I am going with the dynamic arrays instead of the vectors though, so I can work on this competently (hopefully).
BTW: No bother. A bigNum project was a back-burner idea for me anyways. This jump starts it!

I think the following gets both x and y filled by the user and the arrays of integers filled for both, so it's more or less where you were at anyways, but it also sets up an array for z with all elements = 0, so that addition may proceed. Any ideas on how to add the substrings and perform the carry (if there is one) to the next most significant chunk of 8 digits? This would be next.

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
#include <iostream>
#include <string>
using namespace std;

class Big_Nat
{
	private:
		string str;// string representation of BigNum
		int len;// total # of digits in BigNum
		int lastLen;// length of last < 8 digit #
		int Nsubs;// # of 8 digit #'s
		int* pInt;// pointer to an integer, which will be used to dynamically allocate	
			  // Nsubs + 2 integers for the array. This should make the array large enough
			  // for worst case. z may be one digit longer than the longest of x or y
			  // due to carrying of a digit following the summation of x and y

	public:
		void fillIntArray(void);
                void to_string(void);
		int greaterLen( Big_Nat& b );

		// constructors
		Big_Nat();// this one prompts user for string
		Big_Nat( int length);// this one for given length

		// destructor
		~Big_Nat();// will handle deletion of pInt here
};

Big_Nat::Big_Nat()// constructor prompts user for digits
{
	cout << "Enter a big number: ";
	cin >> str;
	len = str.length();
	cout << "len = " << len << endl;
	lastLen = len%8;
	cout << "lastLen = " << lastLen << endl;
	Nsubs = len/8;
	cout << "Nsubs = " << Nsubs << endl;
	pInt = new int[ Nsubs + 2];// array allocated
	// init these values
	for(int j=0; j<(Nsubs + 2); j++)// do not make an error here. A nasty crash results!!
		pInt[j] = 0;
}

Big_Nat::Big_Nat( int length)// constructor is given the # of digits
{	
	len = length;
	cout << "len = " << len << endl;
	lastLen = len%8;
	cout << "lastLen = " << lastLen << endl;
	Nsubs = len/8;
	cout << "Nsubs = " << Nsubs << endl;
	pInt = new int[ Nsubs + 2];// array allocated
	// init these values
	for(int j=0; j<(Nsubs + 2); j++)
		pInt[j] = 0;
}

Big_Nat::~Big_Nat()// destructor
{
	delete [] pInt;
}

int Big_Nat::greaterLen(  Big_Nat& b )
{
	int bigLength = 0;// return value

	if( len > b.len )
		bigLength = len;
	else
		bigLength = b.len;

	cout << "greater length is: " << bigLength << endl;

	return( bigLength );
}

void Big_Nat::fillIntArray(void)
{
	char sub_str[9];

	for(int j=1; j<= Nsubs; j++)// all of the full 8 char cases
	{
		str.copy( sub_str, 8, len - 8*j );// last arg reveals reason for indexing from 1 not 0
		pInt[j-1] = atoi( sub_str );
		cout << "pInt[" << j-1 << "] = " << pInt[j-1] << endl;
	}

	if( lastLen )
	{
		str.copy( sub_str, lastLen, 0 );// this generates a warning about unsafe parameters
		sub_str[ lastLen ] = '\0';// it works because the correct values are being used
		pInt[ Nsubs ] = atoi( sub_str );
		cout << "pInt[" << Nsubs << "] = " << pInt[Nsubs] << endl;
	}
	cout << endl;
	return;
}// end of fillIntArray()

void Big_Nat::to_string(void)
{
	char sub_str[9];
	sub_str[0] = '\0';

	cout << "to_string: ";

	if( lastLen )// partial chunk first	
		_itoa_s( pInt[Nsubs], sub_str, 10 );

	str.assign( sub_str );	

	for(int j=(Nsubs-1); j>= 0; j--)// all of the full 8 char cases, in reverse order
	{
		_itoa_s( pInt[j], sub_str, 10 );
		str.append( sub_str );
	}
	
	cout << str << endl << endl;
	return;
}// end of to_string()

int main()
{
	Big_Nat x;
	x.fillIntArray();
        x.to_string();

	Big_Nat y;
	y.fillIntArray();
        y.to_string();	

	Big_Nat z( x.greaterLen(y) );

	system("PAUSE");// I know, but it's simple and it works.
	return 0;
}// end of main() 


Last edited on
Hey, I think we're stuck on the same part. I like how you're using arrays, since it's easier for me to understand, but I am required to use vectors for this project. For the addition part, I have a feeling that I need to use operator overloading, but am not sure how to implement it into my program...
closed account (D80DSL3A)
Required to use vectors? Uh-Oh. I'm not familiar with the use of vectors (because dynamic arrays have always done the job so-far). Hopefully you can adapt my array based treatment to a vector based treatment.

I'm also really pushing it on the use of strings (believe it or not, I've always used character arrays instead).
Note: I edited my previous post to add the very important function to_string(), which seems to be working. It is also now called in main(), where it is tested. Please test this function thoroughly!

Also, my idea for adding x and y won't involve any operator overloading (another shaky area for me - I've done it just a bit in simple situations).

So, it is not possible for me to spill "the full solution" here. A lot of adaptation is required.

My idea is basically as follows:
z.pInt[0] = x.pInt[0] + y.pInt[0] for the least significant 8 digits

Now, z.pInt[0] may be 9 digits long. I want to equate z.pInt[1] to this 9th (most significant) digit

z.pInt[1] = z.pInt[0]/100000000;// performing the carry

Next, trim the 9th digit from z.pInt[0]

z.pInt[0] = z.pInt[0]%100000000;

Lastly (for z.pInt[1]):
z.pInt[1] += x.pInt[1] + y.pInt[1];


Repeat for z.pInt[2], etc. Do you think this could work?
Will get back to this tomorrow. I'm burnt for now.
Last edited on
closed account (D80DSL3A)
I've found the 1st problem with to_string().
If any 8-digit chunk begins with 1 or more zeros, those zeros don't make it into the string.
My 1st attempt at a workaround failed badly. Nasty crashes!
Any idea how to deal with this case?

However, I have written an add() for Big_Nat based on the idea I presented last post and it is working great!!

The longest case I have tested it for is the following:

x = 2345678901274567890 (19 digits)
y = ____890123456789012 (15 digits)
---------------------------------------------------
z = 2346569024731356902 (19 digits)

EDIT: New max length tested:

x = ___1234567890123456789012345173456789 (34 digits)
y = 4567890123456789012345678901345678901 (37 digits)
-------------------------------------------------------------------------------
z = 4569124691346912469134691246519135690 (37 digits) <- this is output from z.to_string()

I think these are correct.
Please have a try at writing this add() function and let me know how it goes.
Last edited on
closed account (D80DSL3A)
I had to come back to report progress.
I looked into operator overloading and found it was not too tough (about time for me, thanks for the nudge).
Evaluating z = x + y; required that an overloaded assignment operator be defined.
The default copy constructor won't do because of the dynamically allocated array.
The overloaded + operator was easy to adapt from the working add() function.
After folding 2 other function calls into the constructors, I was able to reduce what appears in main() to:

1
2
3
4
5
6
7
int main()
{
    Big_Nat x, y, z(0);
    z = x + y;
	
    return 0;
}

I don't think it can get much more compact than that!
OK - That's it unless there's a response.
Last edited on
fun2code glad to see you are receptive to C++ features like operator overloading. I like it a lot too but please don't abuse this feature.

E.g
Person A; Person B;
Person C = A + B;

Above is classic example where it does not make much "sense" to add 2 person to get a third person unless we are talking about "creation of babies here" :P
sohguanh wrote:
Above is classic example where it does not make much "sense" to add 2 person to get a third person unless we are talking about "creation of babies here" :P

I agree, but fun2code's class is a big integer class (or... something like that...). I think it does make sense to overload some arithmetical operators here :P
Last edited on
I like the way you are going about this. I'm going to look a little deeper into your coding and learn what you have done. Thanks for the help by the way!
Topic archived. No new replies allowed.
Pages: 12