Reversing an input from a file (C++) - c++

I'm creating a very basic program that reads in a list of numbers from a text file, prints them in reverse order, then states if that order is the same as the original (like a palendrome).
I have the program able to print in reverse order so far, but I'm not sure how detect if it's the same as the original file. Any help would be greatly appreciated :)
EDIT: Sorry, had to go away. Here's what I have so far. Got it to reverse, just need to check for palindrome. Will read over replies.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
const int ARRYLENGTH=20;
int contnums[ARRYLENGTH];
int contents;
ifstream myFile("problem3.txt");
if(! myFile )
{
cout << "File cannot be found";
exit(EXIT_FAILURE);
}
while(!myFile.eof())
{
myFile>>contents;
for(int i=0;i<ARRYLENGTH;i++)
{
myFile >> contnums[i];
}
}
cout<<contents<<" ";
for (int i = 1; i < ARRYLENGTH; i++)
{
bool same = false;
for (int j = 0; j < i && (same == false); j++){
if (contnums[i] == contnums[j])
same = true;
}
if (!same) {
cout<< contnums[i] << " ";
}
}
cout << "\n";
system("pause");
myFile.close();
}

I just wondered wether comparing 2 lists would work in std library. It works :-)
#include <list>
#include <fstream>
using std::list;
using std::ifstream;
bool foo(const char * fn)
{
list<int> orig;
list<int> rev;
ifstream ifs(fn,std::ifstream::in);
while( ifs.good() && !ifs.eof() )
{
int num =0;
ifs >> num;
orig.push_back(num);
rev.push_front(num);
}
bool equal = (orig == rev);
return equal;
}
static bool test1 = foo("file1.txt");
static bool test2 = foo("file2.txt");
WHERE
file1.txt contains
1 2 3 4 5 6 7 8 9 0 9 8 7 6 5 4 3 2 1 8
and file2.txt contains
1 2 3 4 5 6 7 8 9 0 9 8 7 6 5 4 3 2 1

Try iterating from begin to end and comparing the values with values of an iterator from end to begin.

If you know how many items you have it could simple be done by:
for(int i = 0; i < count/2; ++i) { //count/2 becouse you only have to check half
if(array[i] != array[count-i-1]) { /*not palindrome */ }
}
//palindrome
Simplest way, but i like #Dave's from comment one better since it ueses STL and iterators in nice way. (As long as you are working on STL container).

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();
}
}
}
}

Inserting a Row into a 2D Vector(vector of vectors)

Relatively new to the C++ scene. Anyways, I have a list:
1 5 6
3 1 2
5 3 4 7
6 2
7 3
I am attempting to fill out the numbers that are missing (in this case, 2 and 4). This list is being inputted as a vector of vectors. That's working fine. My function to insert numbers where they need to be is not. This is my code:
#include<iostream>
#include<vector>
#include<string>
#include<fstream>
#include<sstream>
using namespace std;
int main()
{
vector< vector<int> > vec1;
vector<int> tempVec;
string str = "";
stringstream ss;
int temp = 0;
ifstream iFile;
// iFile.open("E:\\COMP 220\\SCC sample input.txt");
iFile.open("E:\\SCC sample input2.txt");
if (iFile.is_open()) //Inputs file
{
cout << "File is open!\n";
getline(iFile, str);
while (!iFile.eof())
{
int z = 0;
stringstream ss(str);
while (ss >> temp)
{
tempVec.push_back(temp);
cout << tempVec[z] << " ";
z++;
}
vec1.push_back(tempVec);
cout << endl;
tempVec.clear();
getline(iFile, str);
}
}
int count = 0;
while (count < vec1.size() - 1)
{
if (vec1[count][0] != vec1[count + 1][0] - 1)
{
tempVec.clear();
tempVec.push_back(vec1[count][0] + 1);
vec1.insert(count, tempVec);
}
else
count++;
}
return 0;
}
When finished, I was hoping the code would resemble:
1 5 6
2
3 1 2
4
5 3 4 7
6 2
7 3
Any ideas? The current problem is a compiler error with:
vec1.insert(count, tempVec);
You get the compiler error since count is an integer, and std::vector::insert's first parameter is an iterator, not an integer.
To get to a certain position in a vector using an iterator, use the vector::begin() iterator and add on the position:
So this:
vec1.insert(count, tempVec);
should be
vec1.insert(vec1.begin() + count, tempVec);

Is that possible by only using while loop?

My tutor gave me an assignment where I have to write a code that only contains while loop and prints:
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
I tried it 100 times and failed 100 times. Due to my limited knowledge, I began to think that my tutor is just messing with my brain. If it's possible, please introduce me a code that prints the numbers in that order.
Thanks...
int i = 1;
int LIMIT = 5;
while (i <= LIMIT)
{
int j = 1;
while (j <= LIMIT -i) //Loop to print the desired space.
{
cout << " ";
j++;
}
int k = i;
while(k)
{
cout<<k; //Printing the digits
k--;
}
cout << endl; //Adding new line character at the end.
i++;
}
Say hello to your tutor :)
int main(void)
{
char str[11] = " ";// Filled with 10 blank spaces
int i=0;
while(i < 5)
{
str[9 - 2*i] = (i+1) + 48;// +48 will give equivalent ASCII code
printf("%s\n",str);
i++;
}
return 0;
}
Try some code like below. i've also create a sample working code here http://goo.gl/gJqias
#include <iostream>
using namespace std;
int main()
{
int start_Index=1, maximum_Index=5;
while(start_Index<=maximum_Index)
{
//below loop prints leading whitespaces
//note that there are two whitespaces per number
int temp_var=start_Index;
while (maximum_Index-temp_var>0)
{
cout <<" ";
temp_var++;//note the post increment operator.
}
//below whiel loop prints lagging numbers with single whitespace before them
temp_var=start_Index;
while(temp_var>0)
{
cout<<" "<<temp_var--;//note the post decrement operator.
}
//Now we start over to next line
cout<<endl;
//Increment the start_index by 1
start_Index++;
}
return 0;
}

Read integer data from a file

I am just getting started on C++ and am working on codeval questions, so if anyones done that, they'll recognize this problem as it's the first on the list. I need to open a file that has 3 columns of space separated integer values. Here is mine, under fizbuz.txt. I need to get the integer values from the file and store them for later use elsewhere in the program.
1 2 10
3 5 15
4 5 20
2 8 12
2 4 10
3 6 18
2 3 11
8 9 10
2 5 8
4 9 25
Now I can open the file just fine, and I've used getline() to read the files just fine using my below code. However, I don't want them in string format, I'd like them as integers. So I looked around and everyone basically says the same notation (file>>int1>>int2...). I've written some code exactly how I've seen it in a few examples, and it does not behave at all like they're telling me it should.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string filename = "fizbuz.txt";
string line;
int d1,d2,len;
int i =0;
int res1[10], res2[10], length[10];
ifstream read (filename.c_str());
if (read.is_open())
{
// while(read>>d1>>d2>>len);
// {
// res1[i] = d1;
// res2[i] = d2;
// length[i] = len;
// i++;
// }
while (!read.eof())
{
read>>d1>>d2>>len;
res1[i] = d1;
res2[i] = d2;
length[i] = len;
}
read.close();
}
else
{
cout << "unable to open file\n";
}
for (int j = 0; j < 10;j++)
{
cout<< res1[j] << " " << res2[j] << " " << length[j] << '\n';
}
}
Both of the while loops perform the same in the output function at the bottom. The last line of fizbuz.txt will be returned to the first elements of res1,res2 and length, and the remaining elements of all 3 are psuedorandom values, presumably from whatever program was using that memory block before. ex output below
4 9 25
32767 32531 32767
-1407116911 4195256 -1405052128
32531 0 32531
0 0 1
0 1 0
-1405052128 807 -1404914400
32531 1 32531
-1405054976 1 -1404915256
32531 0 32531
The first version should work except that you need to remove the ; in the while line.
while (read >> d1 >> d2 >> len);
^
Try this
while (!read.eof())
{
read>>d1>>d2>>len;
res1[i] = d1;
res2[i] = d2;
length[i] = len;
i++;
}

How to merge two files if the buffer size is smaller than the size of the file?

How to merge two files if the buffer size is smaller than the size of the file?
For example, I have two files with sorted integers
1.txt and 2.txt
2 1
5 7
6 8
7 9
I have to merge them in one sorted file but I can't read more than two numbers from each file(that's the task). And I cant have more than 4 numbers in memory at the same time.
Here is my code
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
const int bufferSize = 2;
bool readSortFile(ifstream &file, vector<int> &data) {
int tmp;
for (int i = 0; (i < bufferSize && file >> tmp); i++)
data.push_back(tmp);
return file.good();
}
int main() {
ifstream file1("1.txt");
ifstream file2("2.txt");
ofstream out;
vector<int> data1, data2;
bool fileGood1, fileGood2;
fileGood1 = true;
fileGood2 = true;
while(fileGood1 || fileGood2) {
if(data1.size() == 0)
fileGood1 = readSortFile(file1, data1);
if (data2.size() == 0)
fileGood2 = readSortFile(file2, data2);
out.open("temp", ios::app);
merge(data1.begin(),
data1.end(),
data2.begin(),
data2.end(),
ostream_iterator<int>(out, "\n"));
data1.clear();
data2.clear();
out.close();
}
rename("temp", "result.txt");
file1.close();
file2.close();
return 0;
}
The output is 1 2 5 7 6 7 8 9
As mentioned in the comment, you only need 1 number from each file to implement a merge, but you'll probably need to write your own merge logic as opposed to using std::merge. Example pseudo code, you'll need to add eof checks (if end of 1.txt, copy rest of 2.txt and vice versa).
num1 = get number from "1.txt"
num2 = get number from "2.txt"
loop(...){
if(num1 <= num2){
write num1
num1 = get number from "1.txt"
} else {
write num2
num2 = get number from "2.txt"
}
}