So this program is supposed to take a string and convert it to Reverse Polish Notation, and then generate the assembly code for it.
For example. If I was to input "x = y", the program would return
"RPN : xy="
"Code:
1 lod y
2 sto x"
However the program instead returns gibberish and continues to do so until it runs out of memory.
Here's the input function
void
getstring()
{
if(datafile) {
file.getline(str,241);
}else{
cout << "Enter a string, please \n\n";
cin.getline( str, 241);
}
nstring++;
}
And these are the functions that work with it.
void
internalize()
{
int i, j;
static char inter[] = {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, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 6, 4, 0, 5, 0, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
0,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,
23,24,25,26,27,28,29,30,31,32,33, 0, 0, 0, 0, 0,
0,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
49,50,51,52,53,54,55,56,57,58,59, 0, 0, 0, 0, 0};
char ch, code, k, *p, *q;
cout << "internal form: \n\n";
k=0;
q=inform;
for(p=str;*p;p++){
*q++ = code = inter[(int)*p];
if(k+code == 0){
k = p-str+1;
ch = *p;
}
}
*q = 0;
for(i=j=0, p = inform;p++,j++;j<len){
cout << setw(3) << (int)*p;
if(++i == 16){
cout << '\n';
i = 0;
}
}
if (i !=0){
cout <<'\n';
}
if((err = (0<k))!=0){
cout << '\n**' << (int)k << "-th nonblank char <" <<ch<<"> is illegal. **\n";
}
}
void
makerpn()
{
static char pr[]={0,0,1,2,3,3,4,4};
char n, *p, *r, s, *t;
cout << "\nRPN:\n\n";
t = stak - 1;
r = rpn;
for (p = inform;p++ ; *p){
if(7 < (s = *p)){
*r++ = s;
//a
}else if(s == 1){
*++t = s;
} else{
while(1){
if(t<stak){
*++t = s;
break;
} else if(pr[s] <= pr[n = *t--]){
*r++ = n;
} else if(3 < n+s){
*++t = n;
*++t = s;
}
break;
}
}
while(stak <= t){
*r++ = *t--;
}
*r = '\0';
for(r=rpn;*r;r++){
cout << ext[(int)*r];
}
cout << "\n\n";
}}
void
gencode()
{
void emit(char, char);
char a,j,lop,n1,n2,*p,*t;
cout << "Generated symbolic code \n\n";
j = len = lop = 0;
t = p = rpn;
while(3 <(a = *++p)){
if(7 <a){
*++t = a;
if((++lop == 2) && (0<len)){
n2=*t--;
n1=*t--;
*++t=j+60;
*++t=n1;
*++t=n2;
emit(2,(j++)+60);
}
}else {
if(lop == 1){
emit(a,*t--);
}else{
if( 1 < lop){
n2 = *t--;
n1 = *t--;
emit(1,n1);
emit(a,n2);
}else {
if((a==4) || (a==6)){
n1 = *t--;
emit(a,n1);
}else {
n1=*t--;
emit(2,j+60);
emit(1,n1);
emit(a,j+60);
if( 59 < n1){
--j;}}}}}}
lop = 0;
}
I'm guessing there is something wrong with the loops but I'm not sure what. I've been tweaking them for a while and all I managed to do was to get it to repeat Hp? instead of HW over and over.
for (p = inform;p++ ; *p) will continue until the next value of p is nullptr, and each round will dereference p and discard the result - you probably meant this the other way around.
Similar is this case: for(i=j=0, p = inform;p++,j++;j<len) which will continue running until j++ becomes 0 and discard the result of the comparision j<len each iteration.
In general, there is really only one problem here: Your code is really, really hard to read. Try to break it down into manageable chunks, and verify each one is doing what you want. That way, if there remains a single chunk not doing what you want, you can identify it, and ask for that one specifically instead of dumping a whole program.
Related
I'm creating a dungeon/rouge-like game in c++ and am trying to implement pathfinding.
The issue I am having is that when the player moves more than two times the adjacency matrix doesn't generate properly. What happens is that every place that the player has been turning to a zero which signifies that you cant go there. I am trying to regenerate the matrix every time the player moves but it doesn't seem to want to. here is the code.
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
int World_Width = 10;
int World_Height = 10;
int Player_X = 1;
int Player_Y = 2;
int Enemy_X = 8;
int Enemy_Y = 1;
int X = Player_X;
int Y = Player_Y;
int Player_Health = 10;
int Enemy_Health = 5;
int Player_Damage = 1;
int Enemy_Damage = 1;
bool PlayerIsAlive = true;
bool EnemyIsAlive = true;
int World[World_Width][World_Height] =
{
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 1, 0, 4, 1},
{1, 2, 0, 0, 0, 0, 1, 0, 0, 1},
{1, 0, 0, 1, 1, 0, 1, 0, 0, 1},
{1, 0, 0, 1, 1, 0, 1, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 1, 0, 0, 1},
{1, 1, 1, 1, 0, 0, 1, 0, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
};
int NodeMap[World_Width][World_Height] =
{
{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, 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, 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, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
};
int NeighborMap[World_Width][World_Height] =
{
{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, 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, 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, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
};
int NodeNumber = 1;
for (int h = 0; h < World_Height; h++)
{
for (int d = 0; d < World_Width; d++)
{
NodeMap[h][d] = NodeNumber;
NodeNumber ++;
}
}
vector<int> queue {};
vector<int> visited {};
string input;
bool AddNode = true;
int QueueNumber = 0;
int Max_iterations = 1000;
int TurnCount = 0;
bool run = true;
while (run)
{
TurnCount += 1;
//Prints out the map
for (int h = 0; h < World_Height; h++)
{
for (int d = 0; d < World_Width; d++)
{
cout << World[h][d] << " ";
}
cout << "\n";
}
cout << "\n";
cout << "Player health: " << Player_Health << "\n";
cout << "Enemy health: " << Enemy_Health << "\n" << "\n";
cout << "What do you want to do; move, attack, or open a chest: ";
//Player movement
cin >> input;
if (input == "w" && World[Player_Y - 1][Player_X] == 0)
{
World[Player_Y ][Player_X] = 0;
Player_Y--;
World[Player_Y][Player_X] = 2;
}
if (input == "a" && World[Player_Y][Player_X - 1] == 0)
{
World[Player_Y][Player_X] = 0;
Player_X--;
World[Player_Y][Player_X] = 2;
}
if (input == "s" && World[Player_Y + 1][Player_X] == 0)
{
World[Player_Y][Player_X] = 0;
Player_Y++;
World[Player_Y][Player_X] = 2;
}
if (input == "d" && World[Player_Y][Player_X + 1] == 0)
{
World[Player_Y][Player_X] = 0;
Player_X++;
World[Player_Y][Player_X] = 2;
}
if (input == "e")
{
if (Player_X == Enemy_X && Player_Y - 1 == Enemy_Y)
{
Enemy_Health -= Player_Damage;
}
if (Player_X == Enemy_X - 1 && Player_Y == Enemy_Y)
{
Enemy_Health -= Player_Damage;
}
if (Player_X == Enemy_X && Player_Y + 1 == Enemy_Y)
{
Enemy_Health -= Player_Damage;
}
if (Player_X == Enemy_X + 1 && Player_Y == Enemy_Y)
{
Enemy_Health -= Player_Damage;
}
}
if ( input == "stop")
{
Player_Health = 0;
}
queue.clear();
QueueNumber = 0;
X = Player_X;
Y = Player_Y;
NeighborMap[Y][X] = 0;
//BFS - Breadth First Search: Pathfinding Algorithim
for (int iterations = 0; iterations < Max_iterations; iterations++)
{
if (World[Y - 1][X] == 0 || World[Y - 1][X] == 4)
{
AddNode = true;
for (int i = 0; i < visited.size(); i++)
{
if (visited[i] == NodeMap[Y - 1][X])
{
AddNode = false;
}
}
if (AddNode)
{
queue.push_back(NodeMap[Y - 1][X]);
NeighborMap[Y - 1][X] = NodeMap[Y][X];
}
}
if (World[Y][X - 1] == 0 || World[Y][X - 1] == 4)
{
AddNode = true;
for (int i = 0; i < visited.size(); i++)
{
if (visited[i] == NodeMap[Y][X - 1])
{
AddNode = false;
}
}
if (AddNode)
{
queue.push_back(NodeMap[Y][X - 1]);
NeighborMap[Y][X - 1] = NodeMap[Y][X];
}
}
if (World[Y + 1][X] == 0 || World[Y + 1][X] == 4)
{
AddNode = true;
for (int i = 0; i < visited.size(); i++)
{
if (visited[i] == NodeMap[Y + 1][X])
{
AddNode = false;
}
}
if (AddNode)
{
queue.push_back(NodeMap[Y + 1][X]);
NeighborMap[Y + 1][X] = NodeMap[Y][X];
}
}
if (World[Y][X + 1] == 0 || World[Y][X + 1] == 4)
{
AddNode = true;
for (int i = 0; i < visited.size(); i++)
{
if (visited[i] == NodeMap[Y][X + 1])
{
AddNode = false;
}
}
if (AddNode)
{
queue.push_back(NodeMap[Y][X + 1]);
NeighborMap[Y][X + 1] = NodeMap[Y][X];
}
}
for (int h = 0; h < World_Height; h++)
{
for (int d = 0; d < World_Width; d++)
{
if(NodeMap[h][d] == queue[QueueNumber])
{
X = d;
Y = h;
}
}
}
visited.push_back(queue[QueueNumber]);
QueueNumber++;
}
//Enemy AI
if (Enemy_Health == 0)
{
if (EnemyIsAlive)
{
World[Enemy_Y][Enemy_X] = 0;
}
EnemyIsAlive = false;
}
if (Player_Health == 0)
{
run = false;
}
}
system("clear");
for (int h = 0; h < World_Height; h++)
{
for (int d = 0; d < World_Width; d++)
{
cout << NeighborMap[h][d] << " ";
}
cout << "\n";
}
cout << "\n";
for (int h = 0; h < World_Height; h++)
{
for (int d = 0; d < World_Width; d++)
{
cout << NodeMap[h][d] << " ";
}
cout << "\n";
}
cout << "GAME OVER" << "\n" << "Thanks for Playing!";
}
I am on Ubuntu 16.04, GCC 5.4, latest OpenCV. Suppose I have a vector of double
std::vector<std::vector<double>> vecvecdouble;
vecvecdouble.resize(3, std::vector<double>(3, 0));
for (int j = 0; j < 3; j++){
for (int i = 0; i < 3; i++){
if (i == 0){
vecvecdouble[i][j] = 1;
vecvecdouble[i][j] = 1;
}
if (i == 1){
vecvecdouble[i][j] = 2;
vecvecdouble[i][j] = 2;
}
if (i == 1 && j == 0){
std::cout << vecvecdouble[i - 1][j] << std::endl;
std::cout << vecvecdouble[i][j] << std::endl;
std::cout << vecvecdouble[i + 1][j] << std::endl;
}
}
}
It prints
1
2
0
as expected. However, if I do the same thing with OpenCV cv::mat
std::vector<std::vector<cv::Mat>> vecvecmat;
vecvecmat.resize(
3, std::vector<cv::Mat>(3, cv::Mat(4, 4, CV_64FC1, cv::Scalar(0.0))));
for (int j = 0; j < 3; j++){
for (int i = 0; i < 3; i++){
if (i == 0){
vecvecmat[i][j].at<double>(0, 0) = 1;
vecvecmat[i][j].at<double>(0, 1) = 1;
}
if (i == 1){
vecvecmat[i][j].at<double>(0, 0) = 2;
vecvecmat[i][j].at<double>(0, 1) = 2;
}
if (i == 1 && j == 0){
std::cout << vecvecmat[i - 1][j] << std::endl;
std::cout << vecvecmat[i][j] << std::endl;
std::cout << vecvecmat[i + 1][j] << std::endl;
}
}
}
It prints
[2, 2, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0]
[2, 2, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0]
[2, 2, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0]
which is completely unexpected because I am expecting it to print
[1, 1, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0;
0, 0, 0, 0]
[2, 2, 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, 0, 0]
However, if I don't try to resize the vector in one single line and go through two for loops it actually returns the expected result
std::vector<std::vector<cv::Mat>> vecvecmat;
vecvecmat.resize(3);
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
cv::Mat mymat = cv::Mat(4, 4, CV_64FC1, cv::Scalar(0.0));
vecvecmat[i].push_back(mymat);
}
}
for (int j = 0; j < 3; j++){
for (int i = 0; i < 3; i++){
if (i == 0){
vecvecmat[i][j].at<double>(0, 0) = 1;
vecvecmat[i][j].at<double>(0, 1) = 1;
}
if (i == 1){
vecvecmat[i][j].at<double>(0, 0) = 2;
vecvecmat[i][j].at<double>(0, 1) = 2;
}
if (i == 1 && j == 0){
std::cout << vecvecmat[i - 1][j] << std::endl;
std::cout << vecvecmat[i][j] << std::endl;
std::cout << vecvecmat[i + 1][j] << std::endl;
}
}
}
What is wrong with the line?
vecvecmat.resize(3, std::vector<cv::Mat>(3, cv::Mat(4, 4, CV_64FC1, cv::Scalar(0.0))));
The documentation for the copy constructor for cv::Mat says (emphasis mine):
Parameters
m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied by these constructors. Instead, the header pointing to m data or its sub-array is constructed and associated with it. The reference counter, if any, is incremented. So, when you modify the matrix formed using such a constructor, you also modify the corresponding elements of m. If you want to have an independent copy of the sub-array, use Mat::clone().
The initial matrix that you construct in your call to std::vector::resize is being copied into each element of the vector with this copy constructor*, so they are all pointing to the same data. When you modify one matrix, you modify all of them.
* or maybe with operator=, which does the same thing (I'm not sure which, but it doesn't affect the result)
I suggest initializing your vector like this:
std::vector<std::vector<cv::Mat>> vecvecmat;
vecvecmat.resize(3, std::vector<cv::Mat>());
for(auto& v : vecvecmat)
{
for(std::size_t i = 0; i < 3; ++i)
{
v.emplace_back(4, 4, CV_64FC1, cv::Scalar(0.0));
}
}
If I have an array that looks like
int digits[size] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4}
I want to remove the leading zeros and to do so I'm attempting to convert the array of integers into a string (which is an array of chars).
My attempt looks like
string toString(int digits[], int size){
string number = " ";
for(int i = 0; i < size - 1; i++){
number[i] = digits[i];
}
return number;
}
which came out horribly broken.
I also can't simply remove all zeros, just the leading ones.
Also if I may dogpile another question here:
how can I identify if a string is numeric?
e.g
string number = "12a4"
cout << "not a number"
you can use C++11 function std::to_string() here is an example
#include <string>
#include <iostream>
int main()
{
int size = 15;
int digits[size] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4};
std::string result = "";
for (int i = 0; i < size; i++)
{
if (!(digits[i] == 0 && result.size() == 0))
result += std::to_string(digits[i]);
}
std::cout << result << std::endl;
}
you can check if a string is numeric using this function
bool isNb(std::string str)
{
if (str.size() == 0)
return false;
for (int i = 0; i < str.size(); i++)
{
if (std::isdigit(str.at(i)) == false)
return false;
}
return true;
}
Instead of changing digits with your for loop, add them with
number += to_string(digits[i]);
Also, you can remove the toString line you have, and just use it as I put here.
As to your other question, just use a for loop to check each digit in the string and its ASCII value, if there is any whose ASCII value is less than 48 or greater than 57 then it's not a number.
Try the following way:
int i = 0;
while(digits[i] == 0) i++;
for (; i < size; i++)
result += to_string(digits[i]);
To answer your actual question (How to remove the leading zeros?) here a solution without strings:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
std::vector<int> x = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4};
// ...or if you insist on the array...
// int x[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4};
// std::vector<int> x = {x,x+15};
auto it = std::find_if_not(x.begin(),x.end(),[](int i){return i==0;});
std::vector<int> y{it,x.end()};
for (auto i : y) std::cout << i << " ";
}
prints:
1 2 3 0 4
You can use a string stream to convert from any type to string:
#include <sstream> //<-- ALLOWS USE OF std::stringstream
const int size = 15;
int digits[size] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 4};
std::stringstream ss; //<-- DECLARE STREAM
int k;
for (k = 0; k < size; ++k)
if (digits[k] != 0)
break; //FIND FIRST NON-0 INDEX
for (int i = k; i < size; ++i)
ss << digits[i]; //ADD TO THE STREAM s
std::cout<< ss.str() << std::endl; //PRINT STREAM
12304
I have a matrix called "temp_matrix" that looks kind of like this:
0.0,100.0,100.0,100.0,
0.0,45.1,60.6,66.2,0,
0.0,45.1,60.6,66.2,0,
0.0,100.0,100.0,100.0,0,
...except mine is a 20x20 matrix.
I've tried:
ofstream excel_plate("plate.csv");
excel_plate.write(temp_matrix[0],20);
excel_plate.close();
cout << endl;
but can't compile.
I've tried:
ofstream excel_plate("plate.csv");
excel_plate << temp_matrix[0], 20, 20;
excel_plate.close();
...but just get a csv file with a string of characters in the very first cell that looks like this: 0052EE98.
Here is my code:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <math.h>
#include <Windows.h>
#include <algorithm>
#include <string>
#include <array>
#undef max
using namespace std;
const double neighbors = 4;
// START FUNCTION: Update Elements
void average(double *temp_matrix, int ROWS, int COLUMNS)
{
int i = 0;
int j = 0;
double row_left = 0;
double row_right = 0;
double column_up = 100;
double column_down = 0;
double sum = 0;
double av = 0;
for (int i = 1; i < ROWS - 1; i++)
{
for (int j = 1; j < COLUMNS - 1; j++)
{
/*
cout << "row_left:" << *(temp_matrix + i*ROWS + (j - 1)) << " ";
cout << "row_right:" << *(temp_matrix + i*ROWS + (j + 1)) << " ";
cout << "column_up:" << *(temp_matrix + (i - 1)*ROWS + j) << " ";
cout << "column_down:" << *(temp_matrix + (i + 1)*ROWS + j) << " ";
*/
row_left = *(temp_matrix + i*ROWS + (j-1));
row_right = *(temp_matrix + i*ROWS + (j + 1));
column_up = *(temp_matrix + (i-1)*ROWS + j);
column_down = *(temp_matrix + (i+1)*ROWS + j);
sum = row_left + row_right + column_up + column_down;
av = sum / neighbors;
*(temp_matrix + i*ROWS + j) = av;
}
}
}
// END FUNCTION: Update Elements
// START FUNCTION: Updtate Until Stable
void update(double *temp_matrix, int ROWS, int COLUMNS)
{
int i = 0;
int j = 0;
double row_left = 0;
double row_right = 0;
double column_up = 100;
double column_down = 0;
double sum = 0;
double old_num = 0;
double new_num = 0;
double difference = 0;
double max_change = .11;
while (max_change > .1)
{
max_change = -1;
for (int i = 1; i < ROWS - 1; i++)
{
for (int j = 1; j < COLUMNS - 1; j++)
{
old_num = *(temp_matrix + i*ROWS + j);
/*
cout << "row_left:" << *(temp_matrix + i*ROWS + (j - 1)) << " ";
cout << "row_right:" << *(temp_matrix + i*ROWS + (j + 1)) << " ";
cout << "column_up:" << *(temp_matrix + (i - 1)*ROWS + j) << " ";
cout << "column_down:" << *(temp_matrix + (i + 1)*ROWS + j) << " ";
*/
row_left = *(temp_matrix + i*ROWS + (j - 1));
row_right = *(temp_matrix + i*ROWS + (j + 1));
column_up = *(temp_matrix + (i - 1)*ROWS + j);
column_down = *(temp_matrix + (i + 1)*ROWS + j);
sum = row_left + row_right + column_up + column_down;
new_num = sum / neighbors;
difference = new_num - old_num;
if (difference > max_change)
{
max_change = difference;
}
*(temp_matrix + i*ROWS + j) = new_num;
}
}
}
}
// END FUNCTION: Update Until Stable
// START FUNCTION: Print Array
void print_array(double *temp_matrix, int ROWS, int COLUMNS)
{
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLUMNS; j++)
{
if (j > 0)
{
cout << ",";
}
cout << fixed << setw(5) << setprecision(1) << *(temp_matrix + i*ROWS + j);
}
cout << endl;
}
}
// END FUNCTION: Print Array
// START FUNCTION: Print 4 Excel
void print_excel(double *temp_matrix, int ROWS, int COLUMNS)
{
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLUMNS; j++)
{
cout << fixed << setprecision(1) << *(temp_matrix + i*ROWS + j) << ",";
}
cout << endl;
}
}
// END FUNCTION: Print 4 Excel
int main()
{
const int ROWS = 20;
const int COLUMNS = 20;
double temp_matrix[ROWS][COLUMNS] =
{
{ 0, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 0 }
};
print_array(temp_matrix[0], 20, 20);
system("pause");
cout << endl << endl;
average(temp_matrix[0], 20, 20);
print_array(temp_matrix[0], 20, 20);
system("pause");
cout << endl << endl;
update(temp_matrix[0], 20, 20);
print_array(temp_matrix[0], 20, 20);
system("pause");
cout << endl << endl;
print_excel(temp_matrix[0], 20, 20);
ofstream excel_plate("plate.csv");
if (excel_plate.is_open())
{
excel_plate << temp_matrix[0], 20, 20;
excel_plate.close();
}
else
{
cout << "Unable to open file.";
}
/*
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLUMNS; j++)
{
if (j > 0)
{
cout << ",";
}
cout << temp_matrix[i][j];
}
cout << endl;
}
*/
system("pause");
return 0;
}
This should be very, very simple. Please kindly help a noob out. :)
P.S. Because this is an assignment, you'll notice that I print out several matrices. The last one I print out is the format in which the matrix needs to be transferred to a .csv file.
The simplest way would be something like the following (assuming you can use c++11)
std::ofstream out("test.csv");
for (auto& row : temp_matrix) {
for (auto col : row)
out << col <<',';
out << '\n';
}
So, this code conatains a functions that should be able to transfer any 2d string array into a csv file
#include <iostream>
#include <fstream>
#include<string>
/* This is for a string array, but if you want to use any other type, just replace
'std::string' with int,double....*/
template <size_t row, size_t col>
void twodarray2csv(std::string(&array)[row][col], std::string filename)
{
std::ofstream myfile;
myfile.open(filename);
for (size_t i = 0; i < row; ++i)
{
for (size_t j = 0; j < col; ++j)
if (j < (col - 1)) {
myfile << array[i][j] << ",";
}
else if (j == (col - 1)) {
myfile << array[i][j] << "\n";
}
}
}
Th template gets the row size and column size and also opens ofstream which is basically for just opening the csv file that will be the output file
int main() {
//example
std::string ArrayName[9][3];
/* this for loop is just there to populate the array, if you have an array
already skip this step */
#include <iostream>
#include <fstream>
#include<string>
/* This is for a string array, but if you want to use any other type, just replace
'std::string' with int,double....*/
template <size_t row, size_t col>
void twodarray2csv(std::string(&array)[row][col], std::string filename)
{
std::ofstream myfile;
myfile.open(filename);
for (size_t i = 0; i < row; ++i)
{
for (size_t j = 0; j < col; ++j)
if (j < (col - 1)) {
myfile << array[i][j] << ",";
}
else if (j == (col - 1)) {
myfile << array[i][j] << "\n";
}
}
}
So the function above uses a template to get the row size and column size of the array, after which it iterates through the array so that when it passes by elements of the same row it adds a comma to the file and at the end of each row it adds a new line (\n) which is a row separator
The part below is an example of how to use it and how it works
First i just created a an Array called ArrayName, and populated it with just some numbers (int number)
int number = 0;
for (int i = 0; i < 9; i++) {
for (int x = 0; x < 3; x++) {
ArrayName[i][x] = number;
number++;
}
}
//this part converts the array to a csv file of desried name
twodarray2csv(ArrayName, "outputfile.csv");
return 0;
}
The output will be a csv file with the name "outputfile.csv" stored in the same folder with the cpp file you have
So I'm trying to code Dijkstra's shortest path algorithm in C++. For some reason, it's not adding up the distances correctly...
Here is what I have so far for code. You can ignore the section where I am copying the path to the stack because I know it's not complete yet. Any ideas where I'm going wrong?
#include <fstream>
#include "matrix.h"
#include <list> // STL container
using namespace std;
//---------------------------------------------------------------------------
const int INFIN = 100000;
const int size = 8;
double a[] = {
0, 0, 5, 0, 0, 2, 3, 0, //length matrix ( #9, page 276)
4, 0, 6, 0, 7, 0, 5, 0,
0, 3, 0, 9, 2, 6, 0, 7,
3, 0, 2, 0, 1, 0, 7, 6,
0, 5, 0, 1, 0, 0, 4, 0,
0, 0, 2, 0, 8, 0, 9, 0,
1, 2, 3, 0, 0, 6, 0, 0,
5, 0, 8, 0, 2, 0, 9, 0
};
// Global declarations for L Matrix and begin and end node
Matrix L(size,size,a); //length matrix
int begin, end;
void path(long* D, int* P); //function prototype for shortest path algorithm
Matrix Warshall(Matrix M);
void main()
{
int i, u;
long D [size+1]; //distance functions
int P [size+1]; //prior vertices in path
cout << "\nLength Matrix: " << L;
cout << "\nPaths that exist:" << Warshall(L);
for (i=1; i <= size; i++) {
D[i] = INFIN; //initialize distance functions
P[i] = 0;
}
cout << "\nFind distance from vertex #";
cin >> begin;
cout << " to vertex #";
cin >> end;
if (begin == end) exit(1);
if (begin < 0 || end < 0) exit(1);
if (begin > size || end > size) exit(1);
path(D,P);
cout << "\nShortest distance from \nvertex #"
<< begin << " to vertex #"
<< end << " is " << D[end];
// u = end;
list<int> stack; // work path backwards
while (1) {
stack.push_front(end);
stack.push_front(begin);
break;
}
cout << "\nusing path:\n";
cout << "\t" << stack.front();
stack.pop_front();
while (stack.size()) {
cout << " -> " << stack.front();
stack.pop_front();
}
getch();
}
void path(long* D, int* P) {
int i, u, dist;
int U[size+1];
for (i=1; i <= size; i++)
U[i] = 0;
U[begin] = 1; // add first vertex;
D[begin] = 0;
u = begin;
do { // until find end vertex
for (i = 1; i <= size; i++) {
dist = L.element(u,i); // distance from u to i
if( D[u] + dist < D[i]) {
D[i] = D[u] + dist;
P[i] = u;
}
}
dist = 38000; // reset distance value to large value
int min;
for(i = 1; i <= size; i++) {
if(L.element(u,i) != 0) {
if(L.element(u,i) < dist && U[i] != 1) {
dist = L.element(u,i);
min = i;
}
}
}
u = min;
U[u] = 1;
cout << "Min is " << min << endl;
} while (u != end);
}
if( D[u] + dist < D[i]) {
D[i] = D[u] + dist;
P[i] = u;
}
should be
if( D[u] + dist < D[i] && dist != 0) {
D[i] = D[u] + dist;
P[i] = u;
}