Structure use in a function C++ - c++

I want to create a function that returns a structure, then run a loop for that function. The idea is basically to calculate the maximum sum, start point and end point of a set of n numbers (1000 in this case) and this for 10 lines in a text file
struct triple
{
float Max;
int sp;
int ep;
};
triple Max_line(string linename, int n)
{
int k, i, stp, enp, j;
triple Result;
float Maxi;
float T[n];
string s;
stringstream ss(linename);
j = 0;
Maxi = 0;
stp = 0;
enp = 0;
while (getline(ss, s, ',')and k < n)
{
T[j] = atof(s.c_str());
j++;
}
for (i = 0; i < n - 1; i++)
{
int k;
float S;
S = T[i];
k = i;
while (k < n - 1)
{
S = S + T[k + 1];
if (S > Maxi)
{
Maxi = S;
stp = i + 1;
enp = k + 2;
}
k++;
}
}
Result = { Maxi, stp, enp }
return Result;
}
int main(int argc, char *argv[]) {
int i, j;
triple fin;
fstream myfile("1000.txt"); //extract data from a file containing 10 lines each has 1000 different numbers
string a, b;
getline(myfile, a); //skip the first line
for (i = 0; i < 10; i++)
{
getline(myfile, b);
fin = Max_line(b, 1000);
cout << fin.Max << ";" << fin.sp << ";" << fin.ep << endl;
}
return 0;
}
When I printed the results inside the Max_line function it gave me the right values, I don't understand why it's not working inside the for loop.
Can anyone help me with that please?

Related

c++ getline file output change when is copied to string

i have a file that each line of it have a row of matrix and in each row, double numbers placed with space between them, this file include a lot of these matrices with a empty line between them
now i have two different versions of code:
1- single thread read from file with getline(file, readLine) and directly process readLine, split it and use stod to make double numbers and make matrix
#include <fstream>
#include <string>
using namespace std;
void decomposeSerial(double *A, long n)
{
long i, j, k;
for (k = 0; k < n; k++) {
for (j = k + 1; j < n; j++)
A[k*n + j] = A[k*n + j] / A[k*n + k];
for (i = k + 1; i < n; i++)
for (j = k + 1; j < n; j++)
A[i*n + j] = A[i*n + j] - A[i*n + k] * A[k*n + j];
}
}
void main() {
const string inFilePath = ".\\data_in\\file.txt";
const string outFilePath = ".\\data_out\\file.txt";
ifstream inFile(inFilePath);
ofstream outFile(outFilePath);
int n;
int matrixLine = 0;
double * matrix = NULL;
string readLine;
while (getline(inFile, readLine)) {
if (!readLine.empty()) {
if (matrixLine == 0) {
n = 0;
string temp = readLine;
size_t pos = 0;
while ((pos = temp.find(" ")) != string::npos) {
temp.erase(0, pos + 1);
n++;
}
matrix = (double *)malloc(sizeof(double) * n * n);
}
size_t pos = 0;
string token;
int i = 0;
while ((pos = readLine.find(" ")) != string::npos) {
token = readLine.substr(0, pos);
matrix[matrixLine * n + i] = stod(token);
readLine.erase(0, pos + 1);
i++;
}
matrixLine++;
if (matrixLine == n) {
decomposeSerial(matrix, n);
double det = 1;
for (long o = 0; o < n; o++) {
det *= matrix[o * n + o];
}
outFile << det << "\n";
}
}
else {
matrixLine = 0;
}
}
inFile.close();
outFile.close();
}
http://codeshare.io/5enk9x
2- single thread read from file with getline(file, readLine) and append readLine to an element of a string array dedicated for this matrix, and after this, in parallel, each thread get one of these elements and go through the same process to make matrix
#include <fstream>
#include <string>
#include <omp.h>
using namespace std;
double det[1000];
string input[1000];
int ns[1000];
void computation(double* src, int n, int l)
{
long i, j, k;
for (k = 0; k < n; k++) {
for (j = k + 1; j < n; j++)
src[k*n + j] = src[k*n + j] / src[k*n + k];
for (i = k + 1; i < n; i++)
for (j = k + 1; j < n; j++)
src[i*n + j] = src[i*n + j] - src[i*n + k] * src[k*n + j];
}
double res = 1;
for (int j = 0; j < n; j++) {
res *= src[j*n + j];
}
det[l] = res;
}
void main() {
const string inFilePath = ".\\data_in\\file.txt";
const string outFilePath = ".\\data_out\\file.txt";
ifstream inFile(inFilePath);
int matrixCount = 0;
bool inMatrix = false;
string readLine;
int dim = 0;
while (getline(inFile, readLine)) {
dim++;
if (readLine.empty()) {
ns[matrixCount] = dim - 1;
dim = 0;
inMatrix = false;
matrixCount++;
}
else {
if (inMatrix == false) {
inMatrix = true;
input[matrixCount] = readLine;
}
else {
input[matrixCount] += readLine;
}
}
}
ns[matrixCount] = dim;
matrixCount++;
inFile.close();
#pragma omp parallel
{
#pragma omp for schedule(dynamic)
for (int i = 0; i < matrixCount; i++) {
string matrixStr = input[i];
int n = ns[i];
double * matrix = (double *)malloc(sizeof(double) * n * n);
size_t pos = 0;
string token;
int k = 0;
while ((pos = matrixStr.find(" ")) != string::npos) {
token = matrixStr.substr(0, pos);
matrix[k] = stod(token);
matrixStr.erase(0, pos + 1);
k++;
}
computation(matrix, n, i);
free(matrix);
}
}
ofstream outFile(outFilePath);
for (int i = 0; i < matrixCount; i++) {
outFile << det[i] << "\n";
}
outFile.close();
}
http://codeshare.io/ad83Yy
but incredibly, second code work much much slower to make matrices
when i print readLine what comes from getline func with printf("%s", readLine) it prints weird chars, anyway i got that when i append readLine to string array element, these weired chars change on the console and i guess that's why i get slower performance as functions line str.find(" ") or stod(str) work better with first weird ones comparing to second ones
if you think the same, you may suggest a way to prevent char changing in appending
These kinds of performance issues can't be reasoned. You need to use a profiler and measure which parts of the code take up how much time.
To start with I would make both codes more similar. There are a lot of differences that could confuse the issue (for once version 1 has a giant memory leak).

Can't pass the test (Kadane's algorithm)

I have to find the maximum sum within a one-dimensional array (1 <= N <= 500000) of integers (|a| <= 4000).
If there are multiple subarrays with the same maximum sum, I have to print the shortest one. If there are multiple shortest subarrays, I have to print the leftmost one.
The code passes most of its tests, except one and I don't know where I did wrong.
The code:
#include <bits/stdc++.h>
using namespace std;
vector<int> adj;
int kStart = 0, kEnd = 0;
void getOutput()
{
ofstream output("max.out");
output << kStart + 1 << " " << kEnd + 1;
output.close();
}
void kadane()
{
int max_global = INT_MIN, max_current = 0, kS = 0;
for(int i = 0; i < adj.size(); i++)
{
max_current += adj[i];
if(max_current > max_global || (max_current == max_global && i - kS < kEnd - kStart))
{
max_global = max_current;
kStart = kS;
kEnd = i;
}
if(max_current < 0)
{
max_current = 0;
kS = i + 1;
}
}
}
void getData()
{
ifstream input("max.in");
int n; input >> n;
for(int i = 0; i < n; i++)
{
int num; input >> num;
adj.push_back(num);
}
input.close();
}
int main()
{
getData();
kadane();
getOutput();
system("pause");
}

How do I get this random number generator out of an infinite loop?

I have an assignment for school where I need to create a lottery program. It is supposed to allow the user to input six numbers and then generate six random numbers for comparison. I got the inputs working, but I have encountered a problem where the random number generator (located in the while loop) is stuck in an infinite loop, and I have absolutely no idea what is causing it since I have never had an infinite loop in any previous programs. If someone could please look through the code and possibly establish what is wrong, I would greatly appreciate it.
#include<iostream>
#include<time.h>
using namespace std;
void randomizeSeed();
int randomRange(int min, int max);
int getInteger();
int main()
{
randomizeSeed();
const int minNumber = 1;
const int maxNumber = 49;
const int Size = 6;
int luckyNumbers[6] = {};
int randomNumber = randomRange(minNumber, maxNumber);
int winningNumbers[6] = {};
cout << "Enter six numbers between 1 and 49...\n";
{
for (int i = 0; i < Size; i++)
{
luckyNumbers[i] = getInteger();
}
for (int i = 0; i < Size; i++)
{
for (int i = 0; i < Size - 1; i++)
{
if (luckyNumbers[i] > luckyNumbers[i + 1])
{
int temp = luckyNumbers[i];
luckyNumbers[i] = luckyNumbers[i + 1];
luckyNumbers[i + 1] = temp;
}
}
}
cout << "Lucky Numbers: ";
for (int i = 0; i < Size; i++)
{
cout << luckyNumbers[i] << " ";
}
cout << "\n";
cout << "Press any button to see the Winning Numbers.\n";
system("pause");
bool exist = true;
while (exist == true)
{
int count = 0;
cout << "Winning Numbers: ";
for (int j = 0; j < 6; j++)
{
winningNumbers[j] = randomRange(1, 49);
cout << winningNumbers[j] << " ";
system("pause");
}
}
}
}
void randomizeSeed()
{
srand(time(NULL));
}
int randomRange(int min, int max)
{
int randomValue = rand() % (max + 1 - min) + min;
return randomValue;
}
int getInteger()
{
int value = 0;
while (!(cin >> value) || (value >= 50) || (value <= 0))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return value;
}
for (int i = 0; i < Size; i++)
for (int i = 0; i < Size - 1; i++)
if (luckyNumbers[i] > luckyNumbers[i + 1])
{
int temp = luckyNumbers[i];
luckyNumbers[i] = luckyNumbers[i + 1];
luckyNumbers[i + 1] = temp;
}
You have two loops and they both use i. You probably mean to use the second loop with another variable name, for example:
for (int i = 0; i < Size; i++)
{
for (int k = 0; k < Size - 1; k++)
{
if (luckyNumbers[i] > luckyNumbers[k + 1])
{
int temp = luckyNumbers[i];
luckyNumbers[i] = luckyNumbers[k + 1];
luckyNumbers[k + 1] = temp;
}
}
}
If you set your compiler warning level to 4 then compiler should warn you about these errors. Try to resolve all compiler warnings.

mtrix chain multiplication print the sequence of the mattrices

I have written code for matrix chain multiplication in dynamic programming in c++.
there is an error in the recursive call for printing the correct parenthesization of the matrices. I am taking input from text file and giving output on a text file. please help..
#include <iostream>
#include <fstream>
#include <limits.h>
using namespace std;
int * MatrixChainOrder(int p[], int n)
{
static int m[100][100];
static int s[100][100];
int j, q;
int min = INT_MAX;
for (int i = 1; i <= n; i++)
m[i][i] = 0;
for (int L = 2; L <= n; L++) {
for (int i = 1; i <= n - L + 1; i++) {
j = i + L - 1;
m[i][j] = min;
for (int k = i; k <= j - 1; k++) {
q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
return (*s);
}
void Print(int *s, int i, int j)
{
ofstream outfile("output.text");
if (i == j)
{
outfile << "a1";
}
else
outfile << "(";
{
Print(*s, i, s[i][j]);
Print(*s, s[i][j] + 1, j);
outfile << ")";
}
outfile.close();
}
int main()
{
int arr[100];
int num, i = 0;
ifstream infile("input.text");
while (infile)
{
infile >> num;
arr[i] = num;
i++;
}
i = i - 1;
infile.close();
Print(MatrixChainOrder(arr, i - 1), 0, i - 1);
return 0;
}
In C++ it is better to use std::vector for arrays. Aside from that, you can't mix pointers and arrays like that because the compiler loses track of array size.
For example this doesn't work:
int x[10][20];
void foo(int *ptr)
{
//the numbers 10 and 20 have not been passed through
}
But you can change it to
int x[10][20];
void foo(int arr[10][20])
{
//the numbers 10 and 20 are available
}
MatrixChainOrder is supposed to return a number, according to this link
int MatrixChainOrder(int s[100][100], int p[], int n)
{
int m[100][100];
for (int i = 0; i < 100; i++) m[i][i] = 0;
for (int i = 0; i < 100; i++) s[i][i] = 0;
int q = 0;
for (int L = 2; L <= n; L++) {
for (int i = 1; i <= n - L + 1; i++) {
int j = i + L - 1;
m[i][j] = INT_MAX;
for (int k = i; k <= j - 1; k++) {
q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
return q;
}
int main()
{
int arr[] = { 40, 20, 30, 10, 30 };
int array_size = sizeof(arr) / sizeof(int);
int n = array_size - 1;
int s[100][100];
int minimum = MatrixChainOrder(s, arr, n);
printf("{ 40, 20, 30, 10, 30 } should result in 26000 : %d\n", minimum);
return 0;
}
Likewise you can change your Print function
void Print(int s[100][100], int i, int j)
{
if (i < 0 || i >= 100 || j < 0 || j >= 100)
{
cout << "array bound error\n";
}
//safely access s[i][j] ...
}

radix sort array of strings

I am trying to use radix sort to sort file contain social security and date of birth the format looks like this "###-##-####,#######.I have to apply radix sort on each fields according to command line switch. I have a radix sort that is work for int array and i am trying to modify the code for string type array but i am not sure how to accomplish this. I did a quick sort for string type by comparing strings and pivot and that is work fine however for radix sort I am not if I can do this with string type or I have to convert the string to integer. I have tried to use "atoi" to convert to integer but I am not sure how to correctly do this if I have to.
string getMax(string arr[], int n){
string max = arr[0];
for (int i = 1; i < n; i++){
if (arr[i]>max)
max = arr[i];
}
return max;
}
void countSort(string a[], int size, int k){
string *b = NULL; int *c = NULL;
b = new string[size];
c = new int[k];
for (int i = 0; i <k; i++){
c[i] = 0;
//cout << c[i] << "\n";
}
for (int j = 0; j <size; j++){
c[(a[j]/k)%10]++; //a[j] is a string
//cout << c[a[j]] << endl;
}
for (int f = 1; f <10; f++){
c[f] += c[f - 1];
}
for (int r = size - 1; r >= 0; r--){
b[c[(a[r] / k) % 10] - 1] = a[r];
c[(a[r] / k) % 10]--;
}
for (int l = 0; l < size; l++){
a[l] = b[l];
}
}
void radixSort(string b[], int r){
string max = getMax(b, r);
for (int digit = 1; max / digit > 0; digit *= 10){
countSort(b, r, digit);
}
};
I didn't try, but I think you can do radix sort for string.
Calculate the length of the longest string in the array to sort.
Do radix sort just like for integers. Do sorting using each characters in the string.
If a string is shorter than another and there is no character in the "digit", consider its value as -65536 (or a smaller value than any other characters).
UPDATE: I tested my idea and it seems working.
#include <cstdio>
#include <string>
using std::string;
size_t getMax(string arr[], int n){
size_t max = arr[0].size();
for (int i = 1; i < n; i++){
if (arr[i].size()>max)
max = arr[i].size();
}
return max;
}
void countSort(string a[], int size, size_t k){
string *b = NULL; int *c = NULL;
b = new string[size];
c = new int[257];
for (int i = 0; i <257; i++){
c[i] = 0;
//cout << c[i] << "\n";
}
for (int j = 0; j <size; j++){
c[k < a[j].size() ? (int)(unsigned char)a[j][k] + 1 : 0]++; //a[j] is a string
//cout << c[a[j]] << endl;
}
for (int f = 1; f <257; f++){
c[f] += c[f - 1];
}
for (int r = size - 1; r >= 0; r--){
b[c[k < a[r].size() ? (int)(unsigned char)a[r][k] + 1 : 0] - 1] = a[r];
c[k < a[r].size() ? (int)(unsigned char)a[r][k] + 1 : 0]--;
}
for (int l = 0; l < size; l++){
a[l] = b[l];
}
// avold memory leak
delete[] b;
delete[] c;
}
void radixSort(string b[], int r){
size_t max = getMax(b, r);
for (size_t digit = max; digit > 0; digit--){ // size_t is unsigned, so avoid using digit >= 0, which is always true
countSort(b, r, digit - 1);
}
}
int main(void) {
string data[] = {
"aaaba",
"dfjasdlifjai",
"jiifjeogiejogp",
"aabaaaa",
"gsgj",
"gerph",
"aaaaaaa",
"htjltjlrth",
"joasdjfisdjfdo",
"hthe",
"aaaaaba",
"jrykpjl",
"hkoptjltp",
"aaaaaa",
"lprrjt"
};
puts("before sorting:");
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); i++) {
printf(" %s\n", data[i].c_str());
}
radixSort(data, (int)(sizeof(data) / sizeof(data[0])));
puts("after sorting:");
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); i++) {
printf(" %s\n", data[i].c_str());
}
return 0;
}