C++ Printing Contents of array backwards One incorrect digit - c++

As part of a program I'm trying to print the contents of an array in reverse order. It is working fine except for one value and I can't figure out why.
I haven't gotten onto functions yet so I haven't used them in my code here is the snippet
case 7:
for (int i = 11; i != -1; i--)// The variable i is initialised to 11. While i is not equal to -1 decrement i by 1.
{
infile >> list[i];//Read in values for array from data.dat
cout << list[i] << " ";// Outputting the array in reverse order.
outfile << "The array in reverse order is: " << list[i] << " " << endl;// Outputting the array in reverse order to file.
}
cout << endl;
break;
The array is filled with the following numbers
8 16 12 6 16 4 8 10 2 16 12 6
The expected output is:
6 12 16 2 10 8 4 16 6 12 16 8
The output I'm getting is:
6 12 16 2 10 8 4 16 6 12 6 8
Any help appreciated

The right way to reverse an iterator is to shift it down by one.
Forward:
T a[N];
for (std::size_t i = 0; i != N; ++i)
{
consume(a[i]);
}
Backward:
T a[N];
for (std::size_t i = 0; i != N; ++i)
{
std::size_t const ri = N - i - 1;
// ^^^
consume(a[ri]);
}
You can write a loop where you actually decrement the loop variable directly, but it's awkward since you either have to use signed integers or otherwise do an additional - 1 when using the index, and it's altogether unnatural, hard to read and easy to get wrong. I'd much rather recommend always using the forward-moving loop as shown here and compute the reverse iterator separately.
Incidentally, this logic is already encapsulated in the iterator wrapper std::reverse_iterator, which is build from a normal, bidirectional moving iterator but decrements by one when being dereferenced. You can either reverse a sequence yourself by using make_reverse_iterator, or by using the free rbegin/rend functions:
#include <iterator>
T a[N];
for (auto rit = std::crbegin(a); rit != std::crend(a); ++rit)
{
consume(*rit);
}

Related

How to read input to a C++ program in reverse order?

Suppose I give input to a C++ program as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
C++ code:
int n;
for (int i = 0; i < 15; i++)
{
std::cin >> n;
// use the value of n to make changes
}
In the above code I can read the input sequentially,
i.e. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15.
Is there any way to read input directly (without using extra memory in C++ program) from the input stream in the following order:
5 4 3 2 1 10 9 8 7 6 15 14 13 12 11
First five digits in reverse order 5 4 3 2 1, next five digits in reverse order 10 9 8 7 6, ...
No.
You need to read the data as they flow into the input stream.
In your program then, you can re-order them in any way you like.
As noted in the comments, the best way to do this is to read them in the order they are given and sort them afterwards.
// vector to hold the values
std::vector<int> values;
values.reserve(15); // reserve for better performance
int n;
for (int i = 0; i < 15; i++)
{
std::cin >> n;
values.push_back(n); // add value to back of vector
}
// sort the vector
std::sort(values.begin(), values.end());
// use the values in ascending order...
for (int i = 0; i < 15; i++) {
std::cout << values[i];
}
Yes this is possible ,but it increase the running time complexity of the code .
First you can make the outer loop for how many series it insert , in the above test case its 3.
Secondly you can make a inner loop which adds the number .
I am not sure the code is running but the logic helps you .
I am implementing the psuedo code using stack !
int n=5;
for(int count = 1 ; count <= 3 ;count++)
{
for(int i=n ; i > n-5 ; i++)
{
push_on_stack(i);
}
n=n+5;
}
You need to wrap your taking input in some functionality that reorders the values for you. You might be able to do so outside the program, i.e., pipe the input stream through another program that reorders the values. Then your code might already work as you have it now.
Or you do this wrapping in your program. For example using a custom stream-like class that buffers the values in between.
There's no way to get this done without using extra memory to buffer the values you don't yet need.
Example:
#include <iostream>
#include <stack>
struct reader {
std::stack<int> data;
reader& operator>>(int & i) {
if (data.empty()) {
while (data.size() < 5) {
data.push(0);
std::cin >> data.top();
}
}
i = data.top();
data.pop();
return *this;
}
explicit operator bool() const { return bool(std::cin); }
};
int main () {
reader r;
int i;
while (r >> i) {
std::cout << i << std::endl;
}
}
Example output:
$ g++ tt.cc -std=c++11 && echo "1 2 3 4 5 6 7 8 9 10" | ./a.out
5
4
3
2
1
10
9
8
7
6
A more straight forward approach would probably be something like this:
#include <iostream>
#include <vector>
int main () {
std::vector<int> buffer;
for (int i; std::cin >> i; ) {
buffer.push_back(i);
if (buffer.size() == 5) {
// do something with buffer
//std::vector<int> reversed(buffer.rbegin(), buffer.rend());
while (!buffer.empty()) {
std::cout << buffer.back() << "\n";
buffer.pop_back();
}
}
}
}

Print the contents of a 2D vector using auto

I have the vector of vectors a, and I want to print out the contents of the first vector.
a = [ 1 5 3 ; 11 17 14 ]
knowing it's size/dimension, I could do that using the following:
for ( int k = 0; k <= a[0].size(); k++)
cout << a[0][k] << endl;
and the output, as I wanted it, is:
1 5 3
However, in another example where the vector changes its size during execution, I tried to use the following:
for ( auto k : a[0])
cout << a[0][k] << endl;
but the output is as the following:
5 0
How can I get the elements of the first vector using the auto keyword without knowing the dimensions of the vector?
When you use the auto keyword, k is being assigned to the value of each element in the vector, not the index of the element. Therefore, if you wanted to print out the contents of the array, print out just k:
for ( auto k : a[0] )
cout << k << endl;
EDIT: For clarity, the reason it works in the first for loop is because you are setting k to be every integer from 0 to the number of elements in a[0], and therefore the index of each element, rather than the value.

Using char arrays to add together large numbers

I have an assignment in which I am supposed to
1.) Read in 2 char arrays of numbers
2.) add together the arrays, performing carry addition, carrying the tens place
3.) print out the newly added array.
I am also supposed to print an error if I need to carry on the last digit of the array (overflow)
so something like 99999999999999999999 +
1 =
________________________
ERROR
That's the part I'm having trouble with.
The above outputs something like "99999999999999999:0" so I have no idea what's going wrong.
I'll post my code, but please be nice :( I know it certainly isn't the most efficient, but I'm just trying to lay things out in a way that is easy for my brain to understand right now.
And yes, I HAVE to use char arrays. I guess it's to help us understand the ascii table.
#include <iostream>
using namespace std;
void InitNumber(char[]);
int AddArrays(char first[], char second[], char combined[]);
void OutputNumber (char[]);
const int LENGTH = 20; // global variable
int main()
{
char set1[LENGTH];
char set2[LENGTH];
char sum[LENGTH];
InitNumber (set1);
InitNumber (set2);
if(AddArrays (set1, set2, sum)) {
cout << "overflow!" << endl;
}
OutputNumber(sum);
}
void InitNumber (char list[])
{
int numberOfDigits;
cout << "Please enter the number of digits in the number: ";
cin >> numberOfDigits;
cout << "Please enter the digits in the number with the LEAST significant first: ";
for (int i = 0; i < numberOfDigits; i++) {
cin >> list [i];
}
for (int l=(numberOfDigits); l < LENGTH; l++) {
list [l] = '0';
}
}
int AddArrays(char first[], char second[], char combined[])
{
for (int h = 0; h < LENGTH; h++)
combined[h]= '0';
int overflow = 0;
for (int i = 0; i < LENGTH; i++) {
int currentSum = (first[i]-'0' + second[i]-'0');
cout << "currentSum = " << currentSum << endl;
if(currentSum / 10 == 0 )
combined[i] += currentSum;
else if (currentSum/10 !=0) {
if (i == LENGTH-1 && currentSum/10 !=0){
overflow = 1;
}
else{
combined [i] += currentSum%10;
cout << "current i: " << combined[i] << endl;
combined [i+1] += currentSum/10;
cout << "current i+1: " << combined[i+1] << endl;
}
}
}
return overflow;
}
void OutputNumber(char arrayOut[])
{
for (int l=LENGTH - 1; l >= 0; l--)
cout << arrayOut[l];
}
working input
input
6
1 2 3 4 5 6
7
1 2 3 4 5 6 7
output
00000000000008308642
Not-working output
input
20
9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9
1
1
output
999999999999999999:0
I'm going to reproduce small parts of your inner loop where you are carrying out the addition, in order to explain why your overflow detection is broken.
for (int i = 0; i < LENGTH; i++) {
int currentSum = (first[i]-'0' + second[i]-'0');
if(currentSum / 10 == 0 )
combined[i] += currentSum;
Here you're adding the corresponding pair of digits from the two numbers you're adding, and checking (in your particular style) if they overflowed. Try to remember this part, it's important. In order to check for overflow, you're only checking the result of adding the pair of digits from the two large numbers you're adding.
else if (currentSum/10 !=0) {
This is a completely useless check. You can only get here if the division is known to produce a non-zero result. This if() can be removed completely. Now, the relevant part of your code is
combined [i] += currentSum%10;
combined [i+1] += currentSum/10;
Do you see the problem yet?
Your approach is, once overflow is detected, is to increment the next higher order digit in the result.
Unfortunately, on the next loop iteration, in order to check for carry over, you're just checking the sum of the next corresponding digit pair, from the two large numbers you're adding. The carry-over you're saving here is going to get completely ignored.
Say your numbers are two digits long max, rather than 20, and you entered the numbers 99 and 1.
On the first iteration, you'll add 9 and 1, save 0 as the first digit, and add 1 to the second digit in the sum.
On the second iteration, you'll add 9 and 0, and, given your logic above, conclude that nothing overflowed.

Iterated Difference

This is an spoj problem. It works, but It's too slow.
Here is the question:
Iterated Difference
You are given a list of N non-negative integers a(1), a(2), ... ,
a(N). You replace the given list by a new list: the k-th entry of the
new list is the absolute value of a(k) - a(k+1), wrapping around at
the end of the list (the k-th entry of the new list is the absolute
value of a(N) - a(1)). How many iterations of this replacement are
needed to arrive at a list in which every entry is the same integer?
For example, let N = 4 and start with the list (0 2 5 11). The successive iterations are:
2 3 6 11
1 3 5 9
2 2 4 8
0 2 4 6
2 2 2 6
0 0 4 4
0 4 0 4
4 4 4 4
Thus, 8 iterations are needed in this example.
Input
The input will contain data for a number of test cases. For each case,
there will be two lines of input. The first line will contain the
integer N (2 <= N <= 20), the number of entries in the list. The
second line will contain the list of integers, separated by one blank
space. End of input will be indicated by N = 0.
Output
For each case, there will be one line of output, specifying the case
number and the number of iterations, in the format shown in the sample
output. If the list does not attain the desired form after 1000
iterations, print 'not attained'.
Sample Input
4
0 2 5 11
5
0 2 5 11 3
4
300 8600 9000 4000
16
12 20 3 7 8 10 44 50 12 200 300 7 8 10 44 50
3
1 1 1
4
0 4 0 4
0
Sample Output
Case 1: 8 iterations
Case 2: not attained
Case 3: 3 iterations
Case 4: 50 iterations
Case 5: 0 iterations
Case 6: 1 iterations
I'm not sure of what to do to make it faster. I tried using arrays, but I get all sorts of problems trying to allocate the memory and set one array to another.
How can I make it faster? Here's my code:
#include <iostream>
#include <vector>
#include <cmath>
#include <sstream>
#include <string>
using namespace std;
bool checker(vector<int>& nums2) {
int n = nums2[0];
for (int i = 1; i < nums2.size(); i++)
{
if (n != nums2[i])
return false;
}
return true;
}
vector<int> iterate(vector<int>& nums, int& iter, bool& attained) {
if (iter == 1000) {
attained = false;
return nums;
}
vector<int> nums2;
for (int i = 0; i < nums.size(); i++) {
if (i == nums.size() - 1)
nums2.push_back((int)abs((double)nums[i] - (double)nums[0]));
else
nums2.push_back((int)abs((double)nums[i] - (double)nums[i + 1]));
}
iter++;
return nums2;
}
int main()
{
int N = -1, count = 1;
while (1) {
int num = 0;
vector<int> nums;
string List = "";
stringstream ss;
cin >> N;
if (N == 0)
break;
cin.ignore();
cin.clear();
getline(cin, List);
ss << List;
while (ss >> num) {
nums.push_back(num);
}
int iterations = 0;
bool attained = true;
while (!checker(nums)) {
nums = iterate(nums, iterations, attained);
}
if (!attained)
cout << "case " << count << ": not attained";
else
cout << "case " << count << ": " << iterations << " iterations" << endl;
count++;
}
}
I fixed it. It was a problem with the while loop in the main function. The condition was:
while (!checker(nums)) { ... }
It would stay in the loop and repeatedly call the iterate function because if it is not attainable, then the checker will always be false. So changing the condition to:
while (!checker(nums) && attained) { ... }
would break the loop if it was not attainable.
Basically, it was just getting stuck on doing the same thing over and over; it wasn't actually slow.
Thanks, xan, for your answer.
If you want it to be a little faster you should work on debugging your array variation to avoid the vector allocations. If you want it to be a lot faster you need to do some analysis of the problem to find a better algorithm. For instance, if you see the same list twice you're in a loop and will exceed 1000 iterations. And the result will be the same if you rotate the list, which you can consider when checking for a repeated list.
Your implementation executes 1000 iterations in 25ms on my mainstream lapton. Fixed one, because there's a bug and case 2 will execute forever.
To do faster you can reuse the same vector and modify it in place, your iterator() function signature would look like:
void iterate(vector<int>& nums);
This version takes 7ms on my machine, because it doesn't allocate memory in loop.

Variable Value Changes By Itself

I've been pretty confused while programming before, but this one takes the cake. Basically I set the value in one for loop, and in the following iteration it changes to the value of the next one.
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < numWords[i]; ++j) //numWords [0] = 9, numWords [1] = 7
{
stb[i][j].word = const_cast<char*>(is (j + 1,1).c_str()); //is(int,length[opt]) converts int to string, c_str() returns const char *, but I need char *
cout << is(j+1,1) << ' ' << stb[i][j].word << '\n';
}
}
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < numWords [i]; ++j)
{
cout << stb[i][j].word << ' ';
}
cout << '\n';
}
Output:
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
1 1
2 2
3 3
4 4
5 5
6 6
7 7
7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7
My only guess now is something with the const, but it doesn't make sense why it would keep changing all previous array elements...
This is pretty simple. Your program has undefined behaviour (if my assumptions about is() are correct).
is(int, length) returns a std::string by value. You get a pointer to some internal structure in that string by using c_str(). This string is then destructed at the end of the full-expression. This destruction invalidates the pointers that you obtained from c_str().
This means that you fill up the array with pointers to invalid memory. You then read from these pointers to print out the contents of the array. Reading from invalid memory results in undefined behaviour.
A possible explanation for the observed behaviour is this:
Each string that is returns reuses the same memory. In the first loop you read from the memory before it has been overwritten by another call to is, and so you get the correct value. In the second loop you read from the memory after it has been overritten, and so you get the final value in the array.