std::getline only reading one line: - c++

I took some code from http://www.cplusplus.com/doc/tutorial/files/ in order to read the character data from a file:
string line;
ifstream myfile ("example.txt");
if (myfile.is_open()) {
while ( getline (myfile,line) ) {
cout << line << '\n';
}
myfile.close();
}
If I create the file with emacs and put in the text data myself, I get exactly what I expected: The entire file is written. But if I try to read in the data from the file I want to read, then I only read the first line.
File1.txt, which doesn't work, has the following hex dump (output truncated):
0000000 1 9 9 8 0 1 0 2 , 9 3 6 , 1 3 .
0000010 3 3 4 5 , 1 3 . 3 3 4 5 , 1 3 .
0000020 3 3 4 5 , 1 3 . 3 3 4 5 , 1 3 4
0000030 8 9 6 , 4 , 0 , 5 \r 1 9 9 8 0 1
0000040 0 2 , 9 3 7 , 1 3 . 3 3 4 5 , 1
0000050 3 . 3 4 5 7 , 1 3 . 3 3 4 5 , 1
0000060 3 . 3 4 5 7 , 1 4 9 8 8 . 5 , 4
0000070 , 0 , 0 \r
File2.txt (which does work) has the following hex dump:
0000000 1 4 0 3 8 0 , 3 2 5 0 0 , 2
0000010 1 4 0 1 4 \n 1 3 1 3 4 , 2
0000020 3 4 8 , 2 3 4 . 0 2 3 , \n 1 2
0000030 3 4 , 1 2 3 4 8 , 1 2 3
0000040 . 3 9 2 4 \n
So clearly one file has a different end-of-line char than the other, but how can I get past this? I'm using MacOSX.

\r is not the default delimiter.
You can set the delimiter for "getline", in the third argument.
getline (myfile,line, '\r');

Related

Vector behaving wierdly

I was trying to find super lucky numbers that is numbers that contain only 4 and 7 as their digit (lucky number) and the number of 4's and 7's must be same (super lucky number). I used recursion to find the lucky numbers and stored them in vector. Then i looped over all lucky elements to check if it is super lucky. But while doing this when i was copying each vector element to another variable for checking its digits, the copy is not working properly. I don't know why it is copying wrong number .
The code goes like:
#include<iostream>
#include<vector>
using namespace std;
vector<long long int> v;
void comb(long long int x){
v.push_back(x);
if(x<10000000){
comb(x*10+4);
comb(x*10+7);
}
}
int main(){
int n,f,s;
long long int n1;
cin>>n;
comb(0);
for(long long int i=1;i<v.size();i++){
n1=v[i]; //here i copied the element to variable
f=0;
s=0;
cout<<n1<<" "; // But when i checked the value of variable it is not equal to element
while(n1>0LL){
if(n1%10LL==4LL){
f++;
}else s++;
n1/=10LL;
}
if(f!=s){
v.erase(v.begin()+i);
}
cout<<v[i]<<" "<<f<<" "<<s<<'\n';
}
return 0;
}
The output goes like:
4 44 1 0 // n1 v[i] f s
444 4444 3 0
44444 444444 5 0
4444444 44444444 7 0
44444447 4444447 7 1
44444474 44444477 7 1
444447 4444474 5 1
44444744 44444747 7 1
4444477 44444774 5 2
44444777 44447 5 3
444474 4444744 5 1
44447444 44447447 7 1
4444747 44447474 5 2
44447477 444477 5 3
4444774 44447744 5 2
44447747 4444777 5 3
44447774 44447777 5 3
4447 44474 3 1
444744 4447444 5 1
44474444 44474447 7 1
4447447 44474474 5 2
44474477 444747 5 3
4447474 44474744 5 2
44474747 4447477 5 3
44474774 44474777 5 3
44477 444774 3 2
4447744 44477444 5 2
44477447 4447747 5 3
44477474 44477477 5 3
444777 444777 3 3
4447774 44477744 4 3
44477747 44477747 4 4
4447777 44477774 3 4
44477777 447 3 5
4474 44744 3 1
447444 4474444 5 1
44744444 44744447 7 1
4474447 44744474 5 2
44744477 447447 5 3
4474474 44744744 5 2
44744747 4474477 5 3
44744774 44744777 5 3
44747 447474 3 2
4474744 44747444 5 2
44747447 4474747 5 3
44747474 44747477 5 3
447477 447477 3 3
4474774 44747744 4 3
44747747 44747747 4 4
4474777 44747774 3 4
44747777 4477 3 5
44774 447744 3 2
4477444 44774444 5 2
44774447 4477447 5 3
44774474 44774477 5 3
447747 447747 3 3
4477474 44774744 4 3
44774747 44774747 4 4
4477477 44774774 3 4
44774777 44777 3 5
447774 447774 3 3
4477744 44777444 4 3
44777447 44777447 4 4
4477747 44777474 3 4
44777477 447777 3 5
4477774 44777744 3 4
44777747 4477777 3 5
44777774 44777777 3 5
47 47 1 1
474 4744 2 1
47444 474444 4 1
4744444 47444444 6 1
47444447 4744447 6 2
47444474 47444477 6 2
474447 4744474 4 2
47444744 47444747 6 2
4744477 47444774 4 3
47444777 47444777 4 4
47447 474474 3 2
4744744 47447444 5 2
47447447 4744747 5 3
47447474 47447477 5 3
474477 474477 3 3
4744774 47447744 4 3
47447747 47447747 4 4
4744777 47447774 3 4
47447777 4747 3 5
47474 474744 3 2
4747444 47474444 5 2
47474447 4747447 5 3
47474474 47474477 5 3
474747 474747 3 3
4747474 47474744 4 3
47474747 47474747 4 4
4747477 47474774 3 4
47474777 47477 3 5
474774 474774 3 3
4747744 47477444 4 3
47477447 47477447 4 4
4747747 47477474 3 4
47477477 474777 3 5
4747774 47477744 3 4
47477747 4747777 3 5
47477774 47477777 3 5
477 4774 1 2
47744 477444 3 2
4774444 47744444 5 2
47744447 4774447 5 3
47744474 47744477 5 3
477447 477447 3 3
4774474 47744744 4 3
47744747 47744747 4 4
4774477 47744774 3 4
47744777 47747 3 5
..........................................
Why is this behaving like this?
You print n1 whatever value it is. Then if it isn't super lucky number, you remove v[i] which is same as n1 then print new v[i], which is the next value of original v[i].

My selection sort replaces some numbers in the array with 0

This is the complete code that I wrote:
( [numsin the function] and [arrin main] is the array that needs to be sorted, sizeis the amount of numbers in the array, minis the smallest number in the unsorted part)
#include <iostream>
#include <vector>
using namespace std;
void sort(vector <int> &nums, int size){
int min = 0;
for(int i=0;i<size;i++){
min = i;
for(int j=i+1;j<size;j++){
if(nums[j]<nums[min]){
min = j; //comparing
}
}
nums[i] = nums[min] + nums[i]; //swaping
nums[min] = nums[i] - nums[min];
nums[i] = nums[i] - nums[min];
}
}
int main(){
cout<<"\nEnter Numbers:\n";
vector <int> arr;
int num;
while(cin>>num){
arr.push_back(num);
}
sort(arr,arr.size());
cout<<"\nSorted:\n";
for(int i=0;i<arr.size();i++){
cout<<arr[i]<<" ";
}
}
I'm writing a code that simply sorts the given array. But after trying to debug and find solutions online, I can't figure out which part is wrong. These are some examples of my results:
Enter Numbers:
9 8 7 6 1 2 3 4 5 ^Z
Sorted:
1 2 3 4 5 6 0 0 0
Enter Numbers:
6 4 8 7 2 3 5 ^Z
Sorted:
2 3 4 5 0 7 0
Enter Numbers:
9 8 7 6 5 4 3 2 1 ^Z
Sorted:
1 2 3 4 0 0 0 0 0
This is the result when I added a for loop under the swapping part to show what every round has done to the array:
Enter Numbers:
9 8 7 6 1 2 3 4 5 ^Z
1 8 7 6 9 2 3 4 5
1 2 7 6 9 8 3 4 5
1 2 3 6 9 8 7 4 5
1 2 3 4 9 8 7 6 5
1 2 3 4 5 8 7 6 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 0 8 9
1 2 3 4 5 6 0 0 9
1 2 3 4 5 6 0 0 0
Sorted:
1 2 3 4 5 6 0 0 0
Enter Numbers:
6 4 8 7 2 3 5 ^Z
2 4 8 7 6 3 5
2 3 8 7 6 4 5
2 3 4 7 6 8 5
2 3 4 5 6 8 7
2 3 4 5 0 8 7
2 3 4 5 0 7 8
2 3 4 5 0 7 0
Sorted:
2 3 4 5 0 7 0
9 8 7 6 5 4 3 2 1 ^Z
1 8 7 6 5 4 3 2 9
1 2 7 6 5 4 3 8 9
1 2 3 6 5 4 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 0 6 7 8 9
1 2 3 4 0 0 7 8 9
1 2 3 4 0 0 0 8 9
1 2 3 4 0 0 0 0 9
1 2 3 4 0 0 0 0 0
Sorted:
1 2 3 4 0 0 0 0 0
Please help, thanks.
Your swapping logic doesn't handle the case where the smallest remaining element is the first unsorted element (i.e., i == min). Consider what each line does in this case:
nums[i] = nums[min] + nums[i]; //nums[i] will be doubled
nums[min] = nums[i] - nums[min]; // nums[min] is subtracted from itself, making it 0
nums[i] = nums[i] - nums[min]; // nums[i] is subtracted from itself gain, but 0-0 is still 0
The goal of avoiding a temporary isn't bad by itself, but you do have this nasty edge case. You'd either have to detect the edge case or just bite the bullet and deal with a temporary. You could also call std::swap, but that likely uses a temporary as well.
The advantage to using a temporary or std::swap is that this code would be easier to make generic for other types (especially via std::swap). In addition, std::swap can be specialized for types to avoid temporaries if possible, and if this is actually a bottleneck.

Stripping off the zeros from a list containing a panda dataframe

i have a list
[0,0,0, DataFrame1,0,0,DataFrame2,0,0, DataFrame3]
where Dataframe is a "Panda Dataframe".
now what i am trying to do is to strip of the '0' zeros (being integers). Is there any way i can do this without using a loop. I tried to use set function, but it is not working with panda Dataframes.
My answer should resemble like this
[ DateFrame1, DataFrame2, DataFrame3]
As #Zero, suggest in comment.
l = []
df = pd.DataFrame(np.random.randint(0,10,(5,5))
l.append(0)
l.append(0)
l.append(df)
l.append(0)
l.append(0)
l.append(df)
print(l)
[0, 0, 0 1 2 3 4
0 5 4 9 6 7
1 9 9 2 7 3
2 4 9 4 8 3
3 4 6 2 5 5
4 8 1 2 1 8, 0, 0, 0 1 2 3 4
0 5 4 9 6 7
1 9 9 2 7 3
2 4 9 4 8 3
3 4 6 2 5 5
4 8 1 2 1 8]
[x for x in l if isinstance(x,pd.DataFrame)]
Output:
[ 0 1 2 3 4
0 5 4 9 6 7
1 9 9 2 7 3
2 4 9 4 8 3
3 4 6 2 5 5
4 8 1 2 1 8, 0 1 2 3 4
0 5 4 9 6 7
1 9 9 2 7 3
2 4 9 4 8 3
3 4 6 2 5 5
4 8 1 2 1 8]

Pandas groupping values to column

I have dataframe look like this:
a b c d e
0 0 1 2 1 0
1 3 0 0 4 3
2 3 4 0 4 2
3 4 1 0 4 3
4 2 1 3 4 3
5 3 2 0 3 3
6 2 1 1 1 0
7 1 1 0 3 3
8 3 3 3 3 4
9 2 3 4 2 2
I do following command:
df.groupby('A').sum()
And i get:
b c d e
a
0 1 2 1 0
1 1 0 3 3
2 5 8 7 5
3 9 3 14 12
4 1 0 4 3
And after that I want to access
labels = df['A']
But I have an error that there are no such column.
So does pandas have some syntax to get something like this?
a b c d e
0 0 1 2 1 0
1 1 1 0 3 3
2 2 5 8 7 5
3 3 9 3 14 12
4 4 1 0 4 3
I need to sum all values of columns b, c, d, e to column a with the relevant index
You can just access the index with df.index, and add it back into your dataframe as another column.
grouped_df = df.groupby('A').sum()
grouped_df['A'] = grouped_df.index
grouped_df.sum(axis=1)
Alternatively, groupby has 'as_index' option to keep the column 'A'
groupby('A', as_index=False)
or, after groupby, you can use reset_index to put the column 'A' back.

Regular Expression to match few characters from a string

I am trying to find a string within another string. However, I am trying to match even if one or more character is not matching.
Let me explain with an example :
Let's say I have a string 'abcdefghij'. Now if the string to match is 'abcd',
I could write strfind('abcdefghij', 'abc')
Now, I have a string 'adcf'. Notice that, there is a mismatch in two characters, I would consider it as a match.
Any idea how to do it ?
I know, this is not the most optimal code.
Example :
a='abcdefghijk';
b='xbcx'
c='abxx'
d='axxd'
e='abcx'
f='xabc'
g='axcd'
h='abxd'
i ='abcd'
All these strings should match with a. I hope this example makes it more clear. The idea is, if there is a mismatch of 1 or 2 characters also, it should be considered as a match.
You could do it like this:
A = 'abcdefghij'; % Main string
B = 'adcf'; % String to be found
tolerance = 2; % Maximum number of different characters to tolerate
nA = numel(A);
nB = numel(B);
pos = find(sum(A(mod(cumsum([(1:nA)' ones(nA, nB - 1)], 2) - 1, nA) + 1) == repmat(B, nA, 1), 2) >= nB - tolerance);
In this case it will return pos = [1 3]'; because "adcf" can be matched on the first position (matching "a?c?") and on the third position (matching "?d?f")
Explanation:
First, we take the sizes of A and B
Then, we create the matrix [(1:nA)' ones(nA, nB - 1)], which gives us this:
Output:
1 1 1 1
2 1 1 1
3 1 1 1
4 1 1 1
5 1 1 1
6 1 1 1
7 1 1 1
8 1 1 1
9 1 1 1
10 1 1 1
We perform a cumulative sum to the right, using cumsum, to achieve this:
Output:
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9
7 8 9 10
8 9 10 11
9 10 11 12
10 11 12 13
And use the mod function so each number is between 1 and nA, like this:
Output:
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9
7 8 9 10
8 9 10 1
9 10 1 2
10 1 2 3
We then use that matrix as an index for the A matrix.
Output:
abcd
bcde
cdef
defg
efgh
fghi
ghij
hija
ijab
jabc
Note this matrix has all possible substrings of A with size nB.
Now we use repmat to replicate B down, 'nA rows'.
Output:
adcf
adcf
adcf
adcf
adcf
adcf
adcf
adcf
adcf
adcf
And perform a direct comparison:
Output:
1 0 1 0
0 0 0 0
0 1 0 1
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
Summing to the right give us this:
Output:
2
0
2
0
0
0
0
0
0
0
Which are the number of character matches on each possible substring.
To finish, we use find to select the indexes of the matches within our tolerance.
In your code
c=a-b is not valid (Matrix dimensions not same)
If you need at least one match, not in order, (as your example says), you can have something like this :-
>> a='abcdefgh';
>> b='adcf';
>> sum(ismember(a,b)) ~= 0
ans =
1