How do I search index of matrix in file? - c++

Suppose, I have a file with 3 column. first 2 column is index of matrix and 3rd column is value of that position in a matrix.
0 0 1
0 1 0
0 2 2
1 0 0
1 1 0
1 2 3
2 0 0
2 1 0
2 2 4
Now i want to search in this file everytime by this loop
for(int a=0; a<8;a=a+2){
for(int b=0; b<8;b=b+2){
for(int c=a; c<2;c++){
for(int d=a; d<2;d++){
//check here c and d is exist in file. if exist then return the 3 column value of that index position and if not then return 0
}
}
}
}
I can not search the value in the whole file every time because it hold the position before the file read in past.please help me I stack on a huge problem in my academia.

Possible solution with std::map for your problem:
First we write every value with the index as key and the value as the mapped value in the map and then we can search for any index:
#include <iostream>
#include <map>
#include <sstream>
#include <string>
int main()
{
std::stringstream stream(
"\
0 0 1\n\
0 1 0\n\
0 2 2\n\
1 0 0\n\
1 1 0\n\
1 2 3\n\
2 0 0\n\
2 1 0\n\
2 2 4\n\
");
std::map<std::pair<int,int>,int> map;
int x, y, value;
while(stream >> x >> y >> value)
{
map.insert({{x, y}, value});
}
int c = 0, d = 2;
auto pos = map.find({c, d});
if(pos != map.end())
{
std::cout << "Value of searched index: " << pos->second << std::endl;
}
return 0;
}

Related

How to read a map file(0s and 1s) and store it into array in C++?

I want to read a file called maze.txt which contains 0s and 1s (indicated blocked or not), and store every element in the file into 2 dimensionals array called maze[17][17].
maze.txt be like :
11111111111111111
10000000000101001
10100111111001101
10101100001010101
10111010100000001
10000011011111001
11111000010001001
10110010000100101
10110100101110111
10000111000100001
10110011000100101
10110010000011101
10111001111110101
10110010000010001
10010111110101111
10010000000000001
11111111111111111
What I've searched the closest answer is using getline() plus istringstream()
(refer to : Read from file in c++ till end of line?)
But above solution only applies when I put a whitespace between each of them, like :
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1
1 0 1 0 0 1 1 1 1 1 1 0 0 1 1 0 1
1 0 1 0 1 1 0 0 0 0 1 0 1 0 1 0 1
1 0 1 1 1 0 1 0 1 0 0 0 0 0 0 0 1
1 0 0 0 0 0 1 1 0 1 1 1 1 1 0 0 1
1 1 1 1 1 0 0 0 0 1 0 0 0 1 0 0 1
1 0 1 1 0 0 1 0 0 0 0 1 0 0 1 0 1
1 0 1 1 0 1 0 0 1 0 1 1 1 0 1 1 1
1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 1
1 0 1 1 0 0 1 1 0 0 0 1 0 0 1 0 1
1 0 1 1 0 0 1 0 0 0 0 0 1 1 1 0 1
1 0 1 1 1 0 0 1 1 1 1 1 1 0 1 0 1
1 0 1 1 0 0 1 0 0 0 0 0 1 0 0 0 1
1 0 0 1 0 1 1 1 1 1 0 1 0 1 1 1 1
1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
My code:
void read_maze(int map[17][17]) {
ifstream read_file("D:/maze.txt", ios::in);
if (read_file.good()){
string str;
int i = 0;
while (getline(read_file, str) {
int j = 0;
istringstream ss(str);
int num;
while (ss >> num)
{
map[i][j] = num;
j++;
}
i++;
}
}
for (int i = 0; i < 17; i++)
{
for (int j = 0; j < 17; j++)
{
cout << map[i][j];
}
cout << endl;
}
read_file.close();
}
output is like original maze.txt
So, what should I do to store each of the element in maze.txt into an array without modifying the content of it?
I believe there might be some easier solutions to it, but since I'm a newbie to C++, I can't find any of similar situations like me.
Hope someone can provide detailed code based on above code.
Thanks a lot!
You can do it like this :
#include <array>
#include <iostream>
#include <string>
#include <sstream>
std::istringstream file{
"11111111111111111\n"
"10000000000101001\n"
"10100111111001101\n"
"10101100001010101\n"
"10111010100000001\n"
"10000011011111001\n"
"11111000010001001\n"
"10110010000100101\n"
"10110100101110111\n"
"10000111000100001\n"
"10110011000100101\n"
"10110010000011101\n"
"10111001111110101\n"
"10110010000010001\n"
"10010111110101111\n"
"10010000000000001\n"
"11111111111111111\n"
};
auto load(std::istream& is)
{
// use std::array, you can actually return that from functions
// and avoids the pain of having to work with double pointers
// and manual memory managment.
std::array<std::array<char, 17>, 17> map{};
// loop over all rows in the map
for (auto& row : map)
{
// loop over all the values in a row
for (auto& value : row)
{
// read one value from the file
is >> value;
}
// newlines will be skipped.
}
// and return your map (2d array)
return map;
}
int main()
{
// file is a stringstream now but
// is easily replaced by a filestream
// (stringstream just makes testing more easy)
auto map = load(file);
// just another range based for loop
// to display the map we read from file.
for (const auto& row : map)
{
for (const auto& value : row)
{
std::cout << value;
}
std::cout << "\n";
}
}
Your code would work with a slight modification. Like this:
#include <fstream>
#include <iostream>
#include <sstream>
using namespace std;
void read_maze(int map[17][17]) {
ifstream read_file("maze.txt", ios::in);
if (read_file.good()){
string str;
int i = 0;
while (getline(read_file, str)) {
// read line and process each digit
for (int j=0; j < str.size(); j++) {
map[i][j] = str[j] - '0';
}
i++;
}
}
for (int i = 0; i < 17; i++)
{
for (int j = 0; j < 17; j++)
{
cout << map[i][j] << " ";
}
cout << endl;
}
read_file.close();
}
int main() {
int map[17][17] = {};
read_maze(map);
}

How to write 2D array with diagonally numbers? [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 7 years ago.
Improve this question
How to write in C++ 2D array with diagonally numbers for
n - size of array (width and height)
x - how many the same number in a row
c - how many numbers must be used
example for
n = 5
x = 2
c = 2
output is:
0 0 1 1 0
0 1 1 0 0
1 1 0 0 1
1 0 0 1 1
0 0 1 1 0
My current code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int n=0, x=0, c=0;
int temp_x=0,temp_c=-1;
cin >> n >> x >> c;
c--;
for(int i=0; i<n;i++){
for(int j=0; j<n;j++){
cout << ++temp_c;
temp_x++;
if(temp_x>x){
temp_x=0;
if(temp_c=c){
temp_c=-1;
}
}
}
cout << endl;
}
}
I will be grateful for your help. :)
But my code return incorrectly number :(
Are you trying to do this?
int main()
{
int n=0, x=0, c=0;
int temp_x=0,temp_c=0;
cin >> n >> x >> c;
c--;
for(int i=0; i<n;i++){
for(int j=0; j<n;j++){
if(temp_x<x)
{
temp_x++;
cout << temp_c << " ";
continue;
}
temp_c++;
temp_x=0;
if(temp_c>c)
{
temp_c=0;
}
cout << temp_c << " ";
temp_x++;
}
cout << endl;
}
}
Output:
5 2 2
0 0 1 1 0
0 1 1 0 0
1 1 0 0 1
1 0 0 1 1
0 0 1 1 0
5 2 3
0 0 1 1 2
2 0 0 1 1
2 2 0 0 1
1 2 2 0 0
1 1 2 2 0
5 3 2
0 0 0 1 1
1 0 0 0 1
1 1 0 0 0
1 1 1 0 0
0 1 1 1 0
I'd like to propose another algorithm:
Run It Online !
#include <iostream>
#include <vector>
#include <numeric> // iota
using std::cout;
using std::endl;
void fill(const size_t n ///< size of array (width and height)
, const size_t x ///< how many the same number in a row
, const size_t c) ///< how many numbers must be used
{
// generate the sequence of possible numbers
std::vector<int> numbers(c);
std::iota(numbers.begin(), numbers.end(), 0);
//std::vector<int> all(n * n); // for storing the output, if needed
for (size_t i = 0, // element index
k = 0, // "number" index
elements = n * n; // the square matrix can also be viewed as a n*n-long, 1D array
i < elements;
k = (k + 1) % c) // next number (and the modulus is for circling back to index 0)
{
// print the number "x" times
for (size_t j = 0; j < x && i < elements; ++j, ++i)
{
// break the line every "n" prints
if ((i % n) == 0)
{
cout << endl;
}
//all[i] = numbers[k];
cout << numbers[k] << " ";
}
}
cout << endl;
}
int main()
{
fill(5, 2, 2);
}
Output for fill(5, 2, 2)
0 0 1 1 0
0 1 1 0 0
1 1 0 0 1
1 0 0 1 1
0 0 1 1 0

C++ Kruskal Algorithm gives out unhandeled exception at runtime

The following code is supposed to find the minimum spanning tree from a adjacency matrix:
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <conio.h>
#include <vector>
#include <string>
using namespace std;
int i, j, k, a, b, u, v, n, ne = 1;
int min, mincost = 0, cost[9][9], parent[9];
int find(int);
int uni(int, int);
int find(int i)
{
while (parent[i]) // Error occurs at this line
i = parent[i];
return i;
}
int uni(int i, int j)
{
if (i != j)
{
parent[j] = i;
return 1;
}
return 0;
}
int main()
{
cout << "MST Kruskal:\n=================================\n";
cout << "\nNo. of vertices: ";
cin >> n;
cout << "\nAdjacency matrix:\n\n";
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
cin >> cost[i][j];
if (cost[i][j] == 0)
cost[i][j] = 999;
}
}
cout << "\nMST Edge:\n\n";
while (ne < n)
{
for (i = 1, min = 999; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
if (cost[i][j] < min)
{
min = cost[i][j];
a = u = i;
b = v = j;
}
}
}
u = find(u);
v = find(v);
if (uni(u, v))
{
cout << ne++ << "th" << " edge " << "(" << a << "," << b << ")" << " = " << min << endl;
mincost += min;
}
cost[a][b] = cost[b][a] = 999;
}
cout << "\nMinimum cost = " << mincost << "\n" << endl;
system("PAUSE");
return 0;
}
It works for 6 number of vertices and the following matrix:
0 3 1 6 0 0
3 0 5 0 3 0
1 5 0 5 6 4
6 0 5 0 0 2
0 3 6 0 0 6
0 0 4 2 6 0
however for 13 vertices and with the following matrix:
0 1 0 0 0 2 6 0 0 0 0 0 0
1 0 1 2 4 0 0 0 0 0 0 0 0
0 1 0 0 4 0 0 0 0 0 0 0 0
0 2 0 0 2 1 0 0 0 0 0 0 0
0 4 4 2 0 2 1 0 0 0 0 4 0
2 0 0 1 2 0 0 0 0 0 0 2 0
6 0 0 0 1 0 0 3 0 1 0 5 0
0 0 0 0 0 0 3 0 2 0 0 0 0
0 0 0 0 0 0 0 2 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0 1 3 2
0 0 0 0 0 0 0 0 1 1 0 0 0
0 0 0 0 4 2 5 0 0 3 0 0 1
0 0 0 0 0 0 0 0 0 2 0 1 0
this error occurs:
Unhandled exception at 0x00ED5811 in KruskalMST.exe: 0xC0000005: Access violation reading location 0x00F67A1C.
The error occurs at line 17: while (parent[i])
VS Autos:
Name Value Type
i 138596 int
parent 0x00ee048c {2, 999, 999, 999, 999, 999, 999, 999, 2} int[9]
[0] 2 int
[1] 999 int
[2] 999 int
[3] 999 int
[4] 999 int
[5] 999 int
[6] 999 int
[7] 999 int
[8] 2 int
You've defined your 'parent' array to have a size of 9 (assuming you have a maximum of 9 vertices, so max number of parents is 9). Six vertices will work because it's less than 9. With thirteen vertices you MAY be accessing elements passed your parent array size; thus, you should try and define your array size depending on the number of vertices.
P.S In general you don't want to have magic numbers in your code.
while (parent[i])
{
i = parent[i];
}
First of all, please use braces to enclose the while statement. Anyone adding another line to it would likely cause undesired behavior.
Your problem is likely that parent[i] assigns a value to i that is outside of the bounds of the parent array.
Try this to see what it's assigning to i:
while (parent[i] != 0)
{
cout << "parent[i] is " << parent[i];
i = parent[i];
}
Since the parent array has a size of 9, if i is ever set to 9 or greater (or less than 0 somehow), you may get an access violation when using parent[i].
Unrelated: It's good to be explicit about what condition you're checking in the while. Before I saw that parent was an int[], I didn't know if it might be an array of pointers, or booleans, I didn't know what the while condition was checking for.
If you want to be safe, bounds check your parent array:
static const int parentSize = 9;
int parent[parentSize];
while (parent[i] != 0 && i > 0 && i < parentSize)
{
cout << "parent[i] is " << parent[i];
i = parent[i];
}
You likely need to increase the parentSize to something larger. If you want something that is more dynamic you might considering using std::vector instead of an array, it can be resized at runtime if you run into a case where the container isn't large enough.

What is resetting the value of the iterator in this for-loop?

#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
double x[SIZE];
for(int i = 2; i <= SIZE; i++) {
x[i] = 0.0;
cout << i << endl;
}
}
Output:
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
...
If SIZE is initialized to a different value, the iterator will iterate until it is one short of that value and then reset back to zero. If the array of x is changed to data type int, the loop does not get stuck on itself. If the assignment value to x[i] is changed to any non-zero number, the value of is changed to garbage during the last run of the loop.
#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
double x[SIZE];
for(int i = 2; i <= SIZE; i++) {
x[i] = 1;
cout << i << endl;
}
}
Output:
2
3
4
1072693248
#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
int x[SIZE];
for(int i = 2; i <= SIZE; i++) {
x[i] = 1;
cout << i << endl;
}
}
Output:
2
3
4
5
You are writing past the end of the x array. x[] ranges from 0 to SIZE - 1 (or 4), and you let your index i == SIZE.
So, the behavior is undefined and coincidentally, you are overwriting i when you write x[5].
Use a debugger. It's your friend.
for(int i = 2; i < SIZE; i++) // i <= SIZE will write beyond the array
Your current array is of size 5. Arrays are 0 indexed:
1st element last element
0 1 2 3 4
You're iterating past the end of your array (i <= 5), which is undefined behavior.
Your end condition is wrong. Use i < SIZE
#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
double x[SIZE];
for(int i = 2; i < SIZE; i++) {
x[i] = 0.0;
cout << i << endl;
}
}

Decide of a routine from the last column on an input file

I am trying to write a rutine for C++ that reads an input file like the following,
1 12 13 0 0 1 0 INLE
2 1 12 0 0 1 0 INLE
3 11 2 0 0 1 0 INLE
4 13 11 0 0 1 0 INLE
5 2 8 0 0 2 0 OUTL
6 8 9 0 0 2 0 OUTL
7 9 10 0 0 2 0 OUTL
8 10 3 0 0 2 0 OUTL
9 4 5 0 0 3 0 SYMP
10 5 6 0 0 3 0 SYMP
11 6 7 0 0 3 0 SYMP
12 7 1 0 0 3 0 SYMP
13 14 4 0 0 4 0 WALL
14 16 14 0 0 4 0 WALL
15 15 16 0 0 4 0 WALL
16 3 15 0 0 4 0 WALL
In this case, I must asign the values of the second and third column to the condition specified on the last column of the right.
Something like,
read the last column;
if it reads the word INLE
{
asign the values of COLUMN2 and COLUMN3 to the pointer &p_InflowNode[i];
}
if it reads the word OUTL
{
asign the values of COLUMN2 and COLUMN3 to the pointer &p_NonrefNode[i];
}
etc...
So my main question is, how can I make C++ to read first the last column, and then decide what to do with the values of the second and third columns?
Thaks
I suggest you do this
struct CData
{
int nC1;
int nC2;
int nC3;
int nC4;
int nC5
int nC6;
int nC7;
string sMode;
friend ifstream& operator >>(ifstream&, struct& CData);
}
You just need to overload the input operator and then
declare an object of the struct and work on it:
struct CData cObj;
ifstream ifIn;
ifIn.open("yourfile.txt");
while(ifIn)
{
ifIn>>cObj;
//now you can use the nested if and else structure here
}
I would suggest if line breaks are consistent to read the file line by line (std::getLine) in a buffer, and check the ending string.
Check line ending
I ended up solving it like this,
#include <fstream>
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
ifstream myfile("ramp.bnd");
string Point1;
string Point2;
string Boundary;
string line,temp;
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
istringstream iss(line);
iss >> temp >> Point1 >> Point2 >> temp >> temp >> temp >> temp >> Boundary;
if (Boundary == "INLE") {
cout << "Inlet condition!!"; //To add more code
}
cout << " \n";
}
myfile.close();
}
else std::cout << "Unable to open file";
myfile.close();
return 0;
}