reading for value in file giving wrong results - c++ - c++

posting again due to change in formatting and code
I'm trying to parse a csv file and search it to find values that match my randomly generated array.
I've tried a few methods but im getting lost, I need to access the entire file, search for these values and output the index column that it belongs to.
my code for my random array generator as well as my search csv function:
reproducible example:
#include <fstream>
#include <iostream>
#include <string>
#include <random>
using namespace std;
//fills array of size 6 with random numbers between 1-50
void random_array(int arr[])
{
for (int i = 0; i < 6; i++) {
int num = rand() % 51;
arr[i] = num;
}
}
int main()
{
string line;
fstream file;
int size = 6;
int numbers[size];
int found;
//gets random array from random_array func
srand(time(NULL));
random_array(numbers);
//opens file to search
file.open("CSV directory here");
if (file.is_open()) {
//print random array values
for (int i = 0; i < size; i++) {
cout << numbers[i] << " ";
}
cout << endl;
//get file contents and search if contents of array exist in file
while (getline(file, line)) {
for (int i = 0; i < size; i++) {
found = line.find(std::to_string(numbers[i]));
if (found != string::npos) {
//print found numbers
cout << found << " ";
}
}
}
}
return 0;
}
CSV sample format:
,Date,1,2,3,4,5,6,7
0,Wed 03 January 2001,5,6,16,17,19,22,40
1,Sat 06 January 2001,6,16,23,34,35,40,37
my output:
array generated:
35 35 38 37 16 31
numbers found (from entire csv not just sample above):
26 33 33 39 24 31 34 33 24 6 28 31 33 33 30 0 32 34 33 30 27 38 26 29
29 33 7 24 29 26 26 26 24 24 0 30 30 36 0 0 23 27 0 0 7 36 36 27 30 30
27 27 26 26 32 29 23 38 32 32 28 28 7 25 29 37 25 29 29 26 23 34 31 28
25 31 28 28 34 32 32 35 38 40 25 37 37 35 40 40 30 30 42 42 42 36 35
28 31 25 37 7 27 36 33 36 33 29 39 29 35 34 34 40 40 43 31
Obviously you can see these numbers aren't correct and are almost completely random. The numbers dont match what's within my array, am I doing something wrong with my file parsing?

Related

How to search a file using an array as search term

I'm trying to parse a csv file and search it to find values that match my randomly generated array.
I've tried a few methods but im getting lost, I need to access the entire file, search for these values and output the index column that it belongs to.
my code for my random array generator as well as my search csv function:
EDIT:
edited code to make reproducible, with added comments, hopefully this matches criteria (besides given csv file obviously).
reproducible example:
#include <fstream>
#include <iostream>
#include <string>
#include <random>
using namespace std;
//fills array of size 6 with random numbers between 1-50
void random_array(int arr[]){
for(int i=0;i<6;i++)
{
int num = rand()%51;
arr[i]=num;
}
}
int main(){
string line;
fstream file;
int size = 6;
int numbers[size];
int found;
//gets random array from random_array func
srand(time(NULL));
random_array(numbers);
//opens file to search
file.open("CSV directory here");
if(file.is_open())
{
//print random array values
for(int i = 0; i < size; i++){
cout << numbers[i]<< " ";}
cout << endl;
//get file contents and search if contents of array exist in file
while(getline(file, line)){
for(int i = 0; i < size; i++){
found = line.find(std::to_string(numbers[i]));
if(found != string::npos) {
//print found numbers
cout << found << " ";
}
}
}
}
return 0;
}
CSV format:
,Date,1,2,3,4,5,6,7
0,Wed 03 January 2001,5,6,16,17,19,22,40
1,Sat 06 January 2001,6,16,23,34,35,40,37
my output:
array generated:
35 35 38 37 16 31
numbers found:
26 33 33 39 24 31 34 33 24 6 28 31 33 33 30 0 32 34 33 30 27 38 26 29
29 33 7 24 29 26 26 26 24 24 0 30 30 36 0 0 23 27 0 0 7 36 36 27 30 30
27 27 26 26 32 29 23 38 32 32 28 28 7 25 29 37 25 29 29 26 23 34 31 28
25 31 28 28 34 32 32 35 38 40 25 37 37 35 40 40 30 30 42 42 42 36 35
28 31 25 37 7 27 36 33 36 33 29 39 29 35 34 34 40 40 43 31
I'd recommend looking at the find function in more detail. None of its overloads take in an integer, the nearest match (and one that would be used) takes in a char ... So it would not be looking for strings like "12" it would be looking for the character which has a value of 12.
You need to first convert the number(s) to a string. A simple modification would be:
for ( int i = 0; i < 6; i++ ) {
if( (offset = line.find( std::to_string( numbers[i] ) ) ) != string::npos ) {
//do something
}
}

Write a program that gives the longest period of days when the temperature was always above K degrees [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
Multiple Selection
My code works fine with the Test 1 inputs but with the Test 2 is stops at the first acceptable indexes and does not continue evaluating other elements and if I remove the break I'm getting off results
Possible Solution
I would like an assistance making the code to continue evaluating other elements even after finding a favorable element
Example Input
Test 1
7 30
25
36
29
33
34
36
30
Test 2
10 30
22
36
31
29
25
36
30
36
36
27
Expected Output
Test 1
4 6
Test 2
6 9
Code
#include <iostream>
using namespace std;
const int MaxN = 102;
void findInd(int T[], int N, int K){
int start = 0; //TODO Recursive
for (int i = 1; i <= N; i++) {
if (N >= 1 && N <= 100 && K >= -20 && K <= 50){
if (T[i] > K && T[i+1] > K){
start = i;
break;
}
}
}
if (start == 0){
cout << "none";
return;
}
int end = start; //TODO recursive
for (int i = N; i >= start; i--) {
if (N >= 1 && N <= 100 && K >= -20 && K <= 50){
if (T[i] > K){
end = i;
break;
}
}
}
cout << start << " " << end;
}
int main() {
int N, K;
cin >> N >> K;
int T[MaxN];
for (int i = 1; i <= N; ++i) {
cin >> T[i];
}
findInd(T, N, K);
return 0;
}
You only need one loop and no recursion, but you need more bookkeeping.
Consider the following example execution for your second case.
v - where you're looking
^ - the start of the current "at least K" range
v
22 36 31 29 25 36 30 36 36 27
max: 0
v
22 36 31 29 25 36 30 36 36 27
^ max: 1, start: 1, end: 1
v
22 36 31 29 25 36 30 36 36 27
^ max: 2, start: 1, end: 2
v
22 36 31 29 25 36 30 36 36 27
max: 2, start: 1, end: 2
v
22 36 31 29 25 36 30 36 36 27
max: 2, start: 1, end: 2
v
22 36 31 29 25 36 30 36 36 27
^ max: 2, start: 1, end: 2
v
22 36 31 29 25 36 30 36 36 27
^ max: 2, start: 1, end: 2
v
22 36 31 29 25 36 30 36 36 27
^ max: 3, start: 5, end: 7
v
22 36 31 29 25 36 30 36 36 27
^ max: 4, start: 5, end: 8
v
22 36 31 29 25 36 30 36 36 27
max: 4, start: 5, end: 8
Implementation left as an exercise.

error: cannot convert ‘double*’ to ‘double’ for argument ‘1’ and error: invalid types ‘double[double]’ for array subscript

I'm trying to bring in a partial data file to fill in an array and the user has three attempts to enter the correct data file name. I have repeatedly have gotten these errors. I understand that an array like arr is just a pointer to a block of memory.
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
void extract (double arr ,int n, double& i, int& error);
int main () {
double arr[256];
int n=256;
double i=0;
int error=0;
extract (arr,n,i,error);
return 0;
}
void extract (double arr, int n, double& i,int& error){
string infile;
string data="data.txt";cout <<"enter data file name/n";
cin >> infile;
while ((error<3) && (data.compare(infile) != 0)){
error++;
cout << "error in input. Please try again/n";
cin >> infile;
}
if (error<3){
ifstream fin;
fin.open("data.txt");
while ((i<n) && (fin >> arr[i])){
i++;
cout << arr[i] << " ";
}
fin.close();}
}
The errors occur in the while loop that inputs the data from the data file into the array.
Changing the Double i to int i replaced the old problem with
error: invalid types ‘double[int]’ for array subscript
Here is my data file
84
87
78
16
94
36
87
93
50
22
63
28
91
60
64
27
41
27
73
37
12
69
68
30
83
31
63
24
68
36
30
3
23
59
70
68
94
57
12
43
30
74
22
20
85
38
99
25
16
71
14
27
92
81
57
74
63
71
97
82
6
26
85
28
37
6
47
30
14
58
25
96
83
46
15
68
35
65
44
51
88
9
77
79
89
85
4
52
55
100
33
61
77
69
40
13
27
87
95
40
Change
void extract (double arr ,int n, double& i, int& error); to void extract (double* arr ,int n, double& i, int& error); both in the definition and declaration of extract function
Edit: The other error is because of double type variable being used as an array index, in your case i in extract function, so either change the type of i to int or use i = static_cast<int>(i) at the very start of extract function, I prefer the first way.
Here is the link of your code along with the changes done and it compiles and works perfectly.
Hope this helps

C++ merge sort passed by value

I am trying to recursively implement the merge sort algorithm by only passing in a vector value to the function (no left or right index). The while loop in the following code works when the list to be sorted is passed as a pointer void merge_sort_array(int* v, int l, int r) or reference void merge_sort_ref(vector<int>& v, int l, int r) but I cannot for the life of me understand why the following code will not properly sort my list. I have a feeling it is something to do with either the starting values of i, j, k or the bounds within my while loop but I've tried anything that makes sense to me and can't figure it out.
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> merge_sort_value(vector<int> v) {
int n = v.size();
if(n == 1){
return v;
}
else{
int m = n/2;
vector<int> v1(v.begin(), v.begin()+m);
vector<int> v2(v.begin()+m, v.begin()+n);
merge_sort_value(v1);
merge_sort_value(v2);
vector<int> tmp(v.begin(), v.begin()+m);
int i = 0;
int j = m;
int k = 0;
while((i < m) or (j < n)){
if(i == m){
v[k] = v[j];
j +=1;
}
else if((j == n) or (tmp[i] < v[j])){
v[k] = tmp[i];
i+=1;
}
else{
v[k] = v[j];
j+=1;
}
k+=1;
# print output for debugging
for(auto x = v.begin(); x != v.end(); ++x)
cout << *x << " ";
cout << "" << endl;
cout << i << "\t"<< j << "\t" << k << endl;
}
return v;
}
}
int main(int argc, char** argv) {
vector<int> v(10);
for(int i=0; i < 10; ++i)
v[i] = rand() % 100;
v = merge_sort_value(v);
return 0;
}
I have included a sample output for reference below:
28 28
0 2 1
28 80
1 2 2
21 21
0 2 1
21 92
1 2 2
14 92 21
1 1 1
14 92 21
1 2 2
14 92 21
1 3 3
14 28 14 92 21
0 3 1
14 80 14 92 21
1 3 2
14 80 28 92 21
2 3 3
14 80 28 92 21
2 4 4
14 80 28 92 21
2 5 5
21 57
1 1 1
21 57
1 2 2
78 83
1 1 1
78 83
1 2 2
78 78 83
0 2 1
78 83 83
0 3 2
78 83 96
1 3 3
21 57 96 78 83
1 2 1
21 57 96 78 83
2 2 2
21 57 96 78 83
2 3 3
21 57 96 78 83
2 4 4
21 57 96 78 83
2 5 5
21 28 14 92 21 21 57 96 78 83
0 6 1
21 57 14 92 21 21 57 96 78 83
0 7 2
21 57 80 92 21 21 57 96 78 83
1 7 3
21 57 80 28 21 21 57 96 78 83
2 7 4
21 57 80 28 14 21 57 96 78 83
3 7 5
21 57 80 28 14 92 57 96 78 83
4 7 6
21 57 80 28 14 92 21 96 78 83
5 7 7
21 57 80 28 14 92 21 96 78 83
5 8 8
21 57 80 28 14 92 21 96 78 83
5 9 9
21 57 80 28 14 92 21 96 78 83
5 10 10
Thank you, any help is greatly appreciated!
after reviewing you code it seems you're making mistakes in the algorithm it self and in C++ as language so i've edited your algorithm to be more neat and more readable algorithm i will explain some part of the code
Code
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> merge_sort_value(vector<int> v) {
int n = v.size();
if(n == 1){
return v;
}
else{
int m = n/2;
vector<int> v1(v.begin(), v.begin()+m);
vector<int> v2(v.begin()+m, v.begin()+n);
v1 = merge_sort_value(v1); /* passing by value will left v1 with no sorting so you need to copy from the returned
object */
v2 = merge_sort_value(v2);
int i = 0;
int j = 0;
int k = 0;
const size_t left_vecS = v1.size();
const size_t right_vecS = v2.size();
while (i<left_vecS&&j<right_vecS) { // we must keep i (AND) j valid
if (v1[i] < v2[j])
v[k++] = v1[i++];
else
v[k++] = v2[j++];
}
while(i<left_vecS) // if we sorted v2 then what insert the rest of v1 in v as what kept from v1 will be sorted
v[k++] = v1[i++];
while(j<right_vecS)
v[k++] = v2[j++];
}
return v;
}
int main(int argc, char** argv) {
vector<int> v(10);
std::vector<int> x;
for(int i=0; i < 10; ++i)
v[i] = rand() % 100;
v = merge_sort_value(v);
for(auto&i:v)
std::cout << i << std::endl;
return 0;
}
1- I get rid of the printing inside the sorting function so we keep the code clean
2-
the first error you've did at the language level is you didn't copy the returned sorted vector object from merge_sort_value to the vectors.(i've mentioned that in the code in a comment) so that's the first thing to keep in mind
3- the logic part of the algorithm wasn't clear to me because i didn't see how you're sorting specially that part else if ((j == n) or (tmp[i] < v[j])) {
v[k] = tmp[i];
i += 1;
}
like you're comparing unsorted sub vector to another unsorted vector and you're giving it unsorted value again (you must compare v1 against v2)
the whole logic is missed up i think you need to review it
anyway i hope that helped

Using an STL map, wrong number of template arguments?

I'm having a little trouble utilizing a map, and I have never really used them before so I am really struggling here
My Code is as follows:
MSTapp.h
5 #ifndef MSTAPP_H
6 #define MSTAPP_H
7
8 #include"Graph.h"
9
10 #include<iostream>
11 #include<map>
12 #include<vector>
13 #include<string>
14
15 using namespace std;
16
17 class MSTapp
18 {
19 public:
20 void read_graph();
21 void print_v();
22 // void print_e();
23
24 private:
25 Graph my_graph;
26 };
27
28 #endif
29
MSTapp.cpp
5 #include"MSTapp.h"
6 #include"Graph.h"
7
8 #include<iostream>
9 #include<map>
10 #include<vector>
11 #include<stdlib.h>
12 #include<sstream>
13 #include<string>
14
15 using namespace std;
16
17 void MSTapp::read_graph()
18 {
19 string s;
20 int count = 0;
21
22 while(getline(cin, s))
23 {
24 if(count == 0)
25 {
26 istringstream my_words(s);
27 string word;
28 while(my_words >> word)
29 {
30 my_graph.add_vertex(word);
31 }
32 }
33 else
34 {
35 string first;
36 string last;
37 int key;
38
39 first = s.substr(0, s.find(" "));
40 s.erase(0,s.find(" ")+1);
41 last = s.substr(0, s.find(" "));
42 s.erase(0,s.find(" ")+1);
43 key = atoi(s.c_str());
44
45 my_graph.add_edge(first, last, key);
46 }
47 }
48 }
49
50 void MSTapp::print_v()
51 {
52 my_graph.print_vertices();
53 }
Graph.h
5 #include"MSTapp.h"
6 #include<map>
7 #include<iostream>
8 #include<string>
9 #include<vector>
10 #include<list>
11
12 using namespace std;
13
14 #ifndef GRAPH_H
15 #define GRAPH_H
16
17 class Graph
18 {
19 public:
20 // Graph();
21 // ~Graph();
22 void add_vertex(string name);
23 void print_vertices();
24 void add_edge(string from, string to, int weight);
25 // void print_edges();
26 // void min_span_tree(string start);
27
28 private:
29 // MinPriority min_queue;
30
31 class Vertex
32 {
33 public:
34 string name;
35 string pi;
36 int key;
37 };
38 class Neighbor
39 {
40 public:
41 string name;
42 int weight;
43 };
44
45 vector<Vertex> vertices;
46 map <string name, list<Neighbor> > adj_list;
4
48 };
49
50 #endif
Graph.cpp
5 #include"MSTapp.h"
6 #include"Graph.h"
7
8 #include<iostream>
9 #include<map>
10 #include<algorithm> // sort
11 #include<string>
12 #include<vector>
13 #include<list>
14
15 using namespace std;
35 void Graph::add_vertex(string name)
36 {
37 Vertex v1;
38 v1.name = name;
39 v1.pi = "NIL";
40 v1.key = 100;
41 bool check;
42
43 for(int i = 0; i < vertices.size(); i++)
44 {
45 if(vertices[i].name == v1.name)
46 {
47 check = true;
48 }
49 }
50
51 if(check == false)
52 {
53 vertices.push_back(v1);
54 }
55 }
56
57 void Graph::print_vertices()
58 {
59 for(int i = 0; i < vertices.size(); i++)
60 {
61 cout << vertices[i].name << " " << vertices[i].pi << " " << vertices[i].key << endl;
62 }
63 }
64
65 void Graph::add_edge(string from, string to, int weight)
66 {
67 string v_from = from;
68 string v_to = to;
69 int v_weight = weight;
70
71 Neighbor n1;
72 n1.name = v_to;
73 n1.weight = v_weight;
74
75 adj_list[v_from];
76 adj_list[v_from].push_back(n1);
77 adj_list[v_from].sort();
78 }
All the functions for the Vertices are working so just ignore those. The main problem I am having is the add_edge function in the Graph. For example my input would be something as follows:
A B C D E //Vertices, this is working
A B 3
so, with the A B 3, I would like to add the B and 3 the the neighbor, and do something like
adj_list[A].push_back(Neighbor)
The errors I am getting are regarding the map, it is saying I have the incorrect number of template arguments for the map in Graph.h.
Am I declaring my map incorrectly on line 46 of Graph.h?
If anyone could provide any insight as to what I am doing wrong or how I can get this working it would be GREATLY appreciated. If any additional clarifcation is needed, just ask. Thanks!
you should declare the map as:
map <string, list<Neighbor> > adj_list;