Histogram Calculating program - c++

#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int arraylength;
int lastbig = 0;
int lastsmall = 0;
int temp = 0;
int numofgroups = 0;
double gg = 0;
cout<<"Enter the number of numbers you are going to enter "<<endl;
cin>>arraylength;
int data[arraylength];
for(int ahmet = 0;ahmet < arraylength;ahmet++)
{
cout<<"Enter the num no."<<ahmet+1<<endl;
cin>>data[ahmet];
}
for(int bbm = 0;bbm < arraylength;bbm++)
{
if(data[bbm]>lastbig)
{
lastbig = data[bbm];
}
}
cout<<"Biggest "<<lastbig<<endl;
for(int ddr = 0;ddr < arraylength;ddr++)
{
if(data[ddr]<lastbig && lastsmall == 0)
{
lastsmall = data[ddr];
}
else if(data[ddr]<lastsmall)
{
lastsmall = data[ddr];
}
}
cout<<"smallest "<<lastsmall<<endl;
temp = lastbig-lastsmall;
cout<<"Enter the number of groups you want"<<endl;
cin>>numofgroups;
gg = (double)temp/numofgroups;
cout<<"gg ="<<gg;
gg = ceil(gg);
cout<<"gg ="<<gg<<endl;
int z = 0;
int lastnumleft = 0;
struct groups {
int min;
int max;
int membercount;
}group[numofgroups];
int tmp = lastsmall;
for(int dinghy = 0;dinghy<numofgroups;dinghy++)
{
if(dinghy == 0)
{
group[dinghy].min = tmp;
group[dinghy].max = tmp + ((int)gg - 1);
tmp = tmp + (int)gg;
}
else{
group[dinghy].min = tmp;
group[dinghy].max = tmp+((int)gg-1);
tmp = tmp + (int)gg;
}
}
for(int jpn = 0;jpn<numofgroups;jpn++)
{
for(int mtr = 0;mtr<arraylength;mtr++)
{
if(data[mtr]>group[jpn].min&&data[mtr]<group[jpn].max)
{
group[jpn].membercount++;
}
}
}
for(int dingil = 0;dingil<numofgroups;dingil++)
{
if(!group[dingil].membercount){
group[dingil].membercount = 0;
}
}
for(int xyz = 0;xyz<numofgroups;xyz++)
{
cout<<group[xyz].min<<" - "<<group[xyz].max<<" "<<group[xyz].membercount<<endl;
}
cin.ignore();
cin.get();
return 0;
}
This program actually does the calculations needed for making a histogram member count of groups and min max of numbers but i cant group the numbers can you help me :)

#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int arraylength;
int lastbig = 0;
int lastsmall = 0;
int temp = 0;
int numofgroups = 0;
double gg = 0;
cout<<"Enter the number of numbers you are going to enter "<<endl;
cin>>arraylength;
int *data = new int[arraylength];
for(int ahmet = 0;ahmet < arraylength;ahmet++)
{
cout<<"Enter the num no."<<ahmet+1<<endl;
cin>>data[ahmet];
}
for(int bbm = 0;bbm < arraylength;bbm++)
{
if(data[bbm]>lastbig)
{
lastbig = data[bbm];
}
}
cout<<"Biggest "<<lastbig<<endl;
for(int ddr = 0;ddr < arraylength;ddr++)
{
if(data[ddr]<lastbig && lastsmall == 0)
{
lastsmall = data[ddr];
}
else if(data[ddr]<lastsmall)
{
lastsmall = data[ddr];
}
}
cout<<"smallest "<<lastsmall<<endl;
temp = lastbig-lastsmall;
cout<<"Enter the number of groups you want"<<endl;
cin>>numofgroups;
gg = (double)temp/numofgroups;
cout<<"gg ="<<gg;
gg = ceil(gg);
cout<<"gg ="<<gg<<endl;
int z = 0;
int lastnumleft = 0;
struct groups {
int min;
int max;
int membercount;
}*group;
group = new groups[numofgroups];
int tmp = lastsmall;
for(int dinghy = 0;dinghy<numofgroups;dinghy++)
{
if(dinghy == 0)
{
group[dinghy].min = tmp;
group[dinghy].max = tmp + ((int)gg - 1);
tmp = tmp + (int)gg;
}
else
{
group[dinghy].min = tmp;
group[dinghy].max = tmp+((int)gg-1);
tmp = tmp + (int)gg;
}
}
for(int jpn = 0;jpn<numofgroups;jpn++)
{
//need to initialize as it has some garbage value and that is what it is printing out.
group[jpn].membercount = 0;
for(int mtr = 0;mtr<arraylength;mtr++)
{
// note the equalities as you need to include the first and the last numbers
if(data[mtr]>=group[jpn].min&&data[mtr]<=group[jpn].max)
{
group[jpn].membercount++;
}
}
}
for(int dingil = 0;dingil<numofgroups;dingil++)
{
if(!group[dingil].membercount){
group[dingil].membercount = 0;
}
}
for(int xyz = 0;xyz<numofgroups;xyz++)
{
cout<<group[xyz].min<<" - "<<group[xyz].max<<" "<<group[xyz].membercount<<endl;
}
cin.ignore();
cin.get();
return 0;
}
It'll work fine now :)

Related

C++ find the second shortest path using Dijkstras algorithm?

I have a Dijkstras algorithm program below. My program reads a text file and finds the shortest path from the start node to the goal node. My question is once this shorest path is discovered, given my code, how can I store this path? Reason being I am required to also find the second shorest path. Thankyou
#include <iostream>
#include <fstream>
#include <vector>
#include <limits.h>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <utility>
using namespace std;
#define INFINITY1 9999
int counter = 0;
int vcount = 0;
int ecount = 0;
int startVertex;
int endVertex;
int nVerticies;
int nEdges;
struct Vertex
{
int label;
int xcord;
int ycord;
};
struct Edge
{
int parent1;
int parent2;
int weight;
};
Vertex *vertArray = NULL;
Edge *edgeArray = NULL;
float distance(int x1, int y1, int x2, int y2)
{
// Calculating distance
return sqrt(pow(x2 - x1, 2) +
pow(y2 - y1, 2) * 1.0);
}
// Dijkstras
void dijkstra(vector<vector<int>> G, int n, int startnode)
{
// Get x and y cords of start node
int startx = vertArray[startnode].xcord;
int starty = vertArray[startnode].ycord;
// Get x and y cords of end node
int endx = vertArray[n].xcord;
int endy = vertArray[n].ycord;
int **cost = new int *[nVerticies];
for (int i = 0; i < nVerticies; ++i)
{
cost[i] = new int[nVerticies];
}
int distance[nVerticies], pred[nVerticies];
int visited[nVerticies], counter, mindistance, nextnode, i, j;
for (i = 0; i < nVerticies; i++)
for (j = 0; j < nVerticies; j++)
// If there is no weight, then set it to infinity
if (G[i][j] == 0)
cost[i][j] = INFINITY1;
else
{
cost[i][j] = G[i][j];
}
for (i = 0; i < nVerticies; i++)
{
distance[i] = cost[startnode][i];
pred[i] = startnode;
visited[i] = 0;
}
distance[startnode] = 0;
visited[startnode] = 1;
counter = 1;
while (counter < nVerticies - 1)
{
mindistance = INFINITY1;
for (i = 0; i < nVerticies; i++)
if (distance[i] < mindistance && !visited[i])
{
mindistance = distance[i];
nextnode = i;
}
visited[nextnode] = 1;
for (i = 0; i < nVerticies; i++)
if (!visited[i])
if (mindistance + cost[nextnode][i] < distance[i])
{
distance[i] = mindistance + cost[nextnode][i];
pred[i] = nextnode;
}
counter++;
}
for(i=n; i<n+1; i++)
if(i!=startnode)
{
cout<<"\nDistance of node "<<i+1<<"="<<distance[i];
cout<<"\nPath="<<i+1;
j=n;
do
{
j=pred[j+1];
cout<<"<-"<<j+1;
}
while(j!=startnode);
}
}
int main()
{
// Declaration for reading file
int a, b, c;
ifstream readFile;
string fileName;
// Ask for file name
cout << "Enter filename: ";
cin >> fileName;
readFile.open(fileName);
// Read last line and set start and goal vertex equal to file input
while (readFile >> startVertex >> endVertex)
{
}
readFile.close();
readFile.open(fileName);
// Read line 1 and set nVerticies and nEdges equal to file input
while (readFile >> nVerticies >> nEdges)
{
counter++;
break;
}
// Create array with size nVerticies
vertArray = new Vertex[nVerticies];
for (int i = 0; i < nVerticies; i++)
{
// Initialise all elements to zero
vertArray[i].label = 0;
vertArray[i].xcord = 0;
vertArray[i].ycord = 0;
}
// Create array with size nEdges
edgeArray = new Edge[nEdges];
for (int i = 0; i < nEdges; i++)
{
// Initialise all elements to zero
edgeArray[i].parent1 = 0;
edgeArray[i].parent2 = 0;
edgeArray[i].weight = 0;
}
vector<vector<int>> G(nVerticies, vector<int>(nVerticies, 0));
while (readFile >> a >> b >> c)
{
// Get vertex from file and add it to array
if (nVerticies >= counter)
{
vertArray[vcount].label = a;
vertArray[vcount].xcord = b;
vertArray[vcount].ycord = c;
vcount++;
counter++;
}
// Get edge from file and add it to array
else
{
G[a - 1][b - 1] = c;
G[b - 1][a - 1] = c;
edgeArray[ecount].parent1 = a;
edgeArray[ecount].parent2 = b;
edgeArray[ecount].weight = c;
ecount++;
counter++;
}
}
readFile.close();
dijkstra(G, endVertex - 1, startVertex - 1);
int n = 11;
int u = 0;
cout << endl;
cout << endl;
cout << endl;
return 0;
}
output from read file
Distance of node 1=46
Path=1<-2
Distance of node 3=65
Path=3<-1<-2
Distance of node 4=47
Path=4<-2
Distance of node 5=36
Path=5<-2
Distance of node 6=53
Path=6<-2
Distance of node 7=135
Path=7<-8<-6<-2
Distance of node 8=99
Path=8<-6<-2
Distance of node 9=95
Path=9<-4<-2
Distance of node 10=82
Path=10<-2
Distance of node 11=116
Path=11<-10<-2
Distance of node 12=76
Path=12<-2
Distance of node 13=85
Path=13<-2
Ive been guided to follow a similar pattern to the following
if you have a path of 1-->2 -->3 -->4
Set 2 to max and try again
Reset 2
Set 3 to max
Reset 3

C++ program getting caught up in _platform_memmove$VARIANT$Haswell

I am trying to use the suggestion from this post to free up time being spent in _platform_memmove$VARIANT$Haswell. According to a time profiler, this is occurring when I send a pointer to several class instances to a function. I have tried changing the way I declare the class instances, changing what the function takes, etc. but have not been able to resolve this.
The chunk of my code that may help:
Inputs *tables = new Inputs(OutputFolder, DataFolder);
ScreenStrat *strat_burnin = new ScreenStrat(ScreenStrat::NoScreen, ScreenStrat::NoScreen,
tables->ScreenStartAge, tables->ScreenStopAgeHIV,
tables->ScreenStopAge, ScreenStrat::NoVaccine);
calibrate *calib_output = new calibrate ();
StateMachine *Machine = new StateMachine();
for (int i = 0; i < n_sims; i++){
calib_output->saved_output[i] = RunCalibration(calib_output->calib_params[i], *strat_burnin, *tables, *Machine);
}
auto ret_val = *calib_output;
delete strat_burnin;
delete tables;
delete Machine;
delete calib_output;
return(ret_val);
and then the function declaration:
vector<double> RunCalibration(vector<double> calib_params, ScreenStrat &strat_burnin, Inputs &tables, StateMachine &Machine)
EDIT
I addressed the points #Botje suggest and it hasn't fixed the problems. Updated code:
void RunCalibration(calibrate &calib, ScreenStrat &strat_burnin, Inputs &tables, StateMachine &Machine, int i);
unique_ptr<calibrate> RunChain(string RunsFileName, string CurKey, string OutputFolder, string DataFolder);
int main(int argc, char* argv[]) {
string DataFolder;
string OutputFolder;
DataFolder = "../Data/";
OutputFolder = "../Output/";
unsigned int run;
string CurKey;
string RunsFileName(DataFolder);
if(argc == 1){
RunsFileName.append("test.ini");
}
else if(argc > 1){
RunsFileName.append(argv[1]);
}
CIniFile RunsFile(RunsFileName);
if (!RunsFile.ReadFile()) {
cout << "Could not read Runs File: " << RunsFileName << endl;
exit(1);
}
CurKey = RunsFile.GetKeyName (0);
if (RunsFile.GetValue(CurKey, "RunType") == "Calibration"){
int totaliters = RunsFile.GetValueI(CurKey, "Iterations");
int n_sims = RunsFile.GetValueI(CurKey, "Simulations");
vector<future<unique_ptr<calibrate>>> futures;
vector<unique_ptr<calibrate>> modeloutputs;
for (run = 0; run < totaliters; run++){
futures.push_back (async(launch::async, RunChain, RunsFileName, CurKey, OutputFolder, DataFolder));
}
for (int i = 0; i < futures.size(); i++){
modeloutputs.push_back (futures[i].get());
} return(0)}
unique_ptr<calibrate> RunChain(string RunsFileName, string CurKey, string OutputFolder, string DataFolder) {
Inputs *tables = new Inputs(OutputFolder, DataFolder);
tables->loadRFG (RunsFileName, CurKey);
tables->loadVariables ();
int n_sims = tables->Simulations;
int n_params = tables->Multipliers.size();
int n_targs = tables->CalibTargs.size();
ScreenStrat *strat_burnin = new ScreenStrat(ScreenStrat::NoScreen, ScreenStrat::NoScreen,
tables->ScreenStartAge, tables->ScreenStopAgeHIV,
tables->ScreenStopAge, ScreenStrat::NoVaccine);
calibrate *calib_output = new calibrate (n_sims, n_params, n_targs);
calib_output->multipliers_names = tables->MultipliersNames;
calib_output->calib_targs_names = tables->CalibTargsNames;
for (int i = 0; i < n_targs; i ++){
calib_output->calib_targs[i] = tables->CalibTargs[i][0];
calib_output->calib_targs_SD[i] = tables->CalibTargs[i][1];
}
for (int i = 0; i < n_params; i++){
for (int j = 0; j < 3; j++){
calib_output->multipliers[i][j] = tables->Multipliers[i][j];
}
}
StateMachine *Machine = new StateMachine();
for (int i = 0; i < n_sims; i++){
RunCalibration(*calib_output, *strat_burnin, *tables, *Machine, i);
}
unique_ptr<calibrate> ret_val = make_unique<calibrate>(*calib_output);
delete strat_burnin;
delete tables;
delete Machine;
delete calib_output;
return(ret_val);
}
void RunCalibration(calibrate &calib, ScreenStrat &strat_burnin, Inputs &tables, StateMachine &Machine, int i){
Adding in Calibrate definition per request from #botje
#include "calibrate.h"
using namespace std;
calibrate::calibrate(int n_sims, int n_params, int n_targs) {
calib_targs.resize (n_targs);
calib_targs_SD.resize (n_targs);
multipliers.resize(n_params);
for(int i = 0; i < n_params; i++){
multipliers[i].resize(3);
}
calib_params.resize (n_sims);
for (int i = 0; i < calib_params.size(); i++){
calib_params[i].resize (n_params);
}
saved_output.resize (n_sims);
for (int i = 0; i < saved_output.size(); i++){
saved_output[i].resize (n_targs);
}
best_params.resize (n_params);
GOF.clear();
tuned_SD.resize(n_params);
}
calibrate::~calibrate(void) {
}
void calibrate::CalculateGOF(int n_sims) {
GOF.push_back (WeightedDistance (saved_output[n_sims][0], calib_targs[0], calib_targs_SD[0]));
for (int i = 1; i < calib_targs.size(); i ++){
GOF[n_sims] += WeightedDistance (saved_output[n_sims][i], calib_targs[i], calib_targs_SD[i]);
}
if (n_sims == 0){
GOF_min = GOF[0];
best_params = calib_params[0];
} else {
auto it = std::min_element(std::begin(GOF), std::end(GOF));
int index = distance(GOF.begin(), it);
GOF_min_run = GOF[index];
if (GOF_min_run < GOF_min){
GOF_min = GOF_min_run;
best_params = calib_params[index];
}
}
}
std::vector<double> calibrate::loadCalibData(int n_params, int n_sim, int tuning_factor) {
if(n_sim == 0){
random_device rd;
mt19937 gen(rd());
for (int i = 0; i < n_params; i ++ ){
uniform_real_distribution<> dis(multipliers[i][0], multipliers[i][1]);
calib_params[n_sim][i] = dis(gen);
}
} else {
tuned_SD = tuningparam (n_sim, n_params, tuning_factor);
for (int i = 0; i < n_params; i ++ ){
calib_params[n_sim][i] = rnormal_trunc (best_params[i], tuned_SD[i], multipliers[i][1], multipliers[i][0]);
}
}
return(calib_params[n_sim]);
}
double calibrate::WeightedDistance(double data, double mean, double SD) {
double distance = pow((data - mean)/(SD * 2),2);
return distance;
}
double calibrate::rnormal_trunc(double mu, double sigma, double upper, double lower) {
std::default_random_engine generator;
std::normal_distribution<double> distribution(mu, sigma);
double prob = distribution(generator);
while (prob < lower || prob > upper){
prob = distribution(generator);
}
return(prob);
}
vector<double> calibrate::tuningparam(int n_sims, int n_param, int tuning_factor) {
vector<double> newSD;
for (int i = 0; i < n_param; i++){
newSD.push_back (multipliers[i][2]/pow(tuning_factor,n_sims));
}
return newSD;
}
I improved RunCalibration as follows. Note the comments for further improvement opportunities.
using std::make_unique;
using std::unique_ptr;
void RunCalibration(calibrate &calib, ScreenStrat &strat_burnin, Inputs &tables, StateMachine &Machine, int i);
unique_ptr<calibrate> RunChain(string RunsFileName, string CurKey, string OutputFolder, string DataFolder) {
auto tables = make_unique<Inputs>(OutputFolder, DataFolder);
tables->loadRFG (RunsFileName, CurKey);
tables->loadVariables ();
int n_sims = tables->Simulations;
int n_params = tables->Multipliers.size();
int n_targs = tables->CalibTargs.size();
auto strat_burnin = make_unique<ScreenStrat>(
ScreenStrat::NoScreen, ScreenStrat::NoScreen,
tables->ScreenStartAge, tables->ScreenStopAgeHIV,
tables->ScreenStopAge, ScreenStrat::NoVaccine);
auto calib_output = make_unique<calibrate>(n_sims, n_params, n_targs);
// I don't know the type of these fields, but IF you do not modify them in
// `RunCalibration`, consider making them `shared_ptr<vector<...>>`
// both in `calibrate` and in `Inputs` so you can simply copy
// the pointer instead of the full table.
calib_output->multipliers_names = tables->MultipliersNames;
calib_output->calib_targs_names = tables->CalibTargsNames;
// Same applies here. If you do not modify CalibTargs, make `calib_targs` a shared_ptr
// and only copy by pointer.
for (int i = 0; i < n_targs; i ++){
calib_output->calib_targs[i] = tables->CalibTargs[i][0];
calib_output->calib_targs_SD[i] = tables->CalibTargs[i][1];
}
// and again...
for (int i = 0; i < n_params; i++){
for (int j = 0; j < 3; j++){
calib_output->multipliers[i][j] = tables->Multipliers[i][j];
}
}
auto Machine = make_unique<StateMachine>();
for (int i = 0; i < n_sims; i++){
RunCalibration(*calib_output, *strat_burnin, *tables, *Machine, i);
}
// This will return the unique_ptr without copying.
return calib_output;
}

passing a double pointer boolean array to a function

I have a double pointer boolean.
I would like to pass this boolean to a function
The code is used for graph theory, to create an adj matrix, check if the graph has cycles or not ...
The problem comes from the cycle function
The function doesn't like the boolean in parameter to check if a graph has a cycle.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
int Cycle(int number_of_vertices ,bool **adj_matrix)
{
bool** adj = new bool*[number_of_vertices];
for(int i=0;i<number_of_vertices;i++)
{
adj[i] = new bool[number_of_vertices];
}
for(int i=0;i<number_of_vertices;i++)
{
for(int j=0;j<number_of_vertices;j++)
{
adj[i][j] = adj_matrix[i+1][j+1];
}
}
for(int k=0;k<number_of_vertices;k++)
{ // transitiv closure
for(int i=0;i<number_of_vertices;i++)
{
for(int j=0;j<number_of_vertices;j++)
{
if(adj[i][k]&&adj[k][j])
{
adj[i][j] = true;
}
}
}
}
int count = 0;
for(int i=0;i<number_of_vertices;i++)
{
if(adj[i][i])
{
count++;
}
}
return count;
}
int main()
{
string first_line, second_line;
int initial_extremity, final_extremity, value, number_of_vertices, nombre_arcs;
ifstream fichier("test.txt");
bool** adj_matrix;
int** val_matrix;
vector<int> vertice_names;
if (fichier.is_open())
{
getline(fichier, first_line);
number_of_vertices = atoi(first_line.c_str());
getline(fichier, second_line);
nombre_arcs = atoi(second_line.c_str());
adj_matrix = new bool*[number_of_vertices];
val_matrix = new int*[number_of_vertices];
for (int i=0; i<number_of_vertices;i++)
{
adj_matrix[i] = new bool[number_of_vertices];
val_matrix[i] = new int[number_of_vertices];
for (int j=0; j<number_of_vertices; j++)
{
adj_matrix[i][j] = false;
val_matrix[i][j] = 0;
}
}
while(fichier >> initial_extremity >> final_extremity >> value)
{
adj_matrix[initial_extremity][final_extremity] = true;
val_matrix[initial_extremity][final_extremity] = value;
int c = Cycle(number_of_vertices, adj_matrix);
printf("number of cycles: %d\n\n", c);
if(c!=0)
{
printf("%d --[%d]--> %d\n",initial_extremity,value,final_extremity);
}
else
{
printf("%d --[%d]--> %d\n",initial_extremity,value,final_extremity);
}
if ( find(vertice_names.begin(), vertice_names.end(), initial_extremity) != vertice_names.end() )
{
//nothing
}
else
{
vertice_names.push_back(initial_extremity);
}
if ( find(vertice_names.begin(), vertice_names.end(), final_extremity) != vertice_names.end() )
{
//nothing
}
else
{
vertice_names.push_back(final_extremity);
}
}
fichier.close();
}
else
{
cout << "error while opening the file" << '\n';
cin.get();
}
printf("%d arcs\n",nombre_arcs);
printf("%d vertices\n\n\n",number_of_vertices);
printf("Adj Matrix \n");
printf(" ");
for(int i = 0; i<number_of_vertices; i++)
{
printf("%3d",vertice_names.at(i));
}
printf("\n");
for (int i = 0; i<number_of_vertices; i++)
{
printf("%3d ", vertice_names.at(i));
for (int j = 0; j <number_of_vertices; j++)
{
printf("%3d",adj_matrix[i][j]);
}
printf("\n");
}
printf("\n\n");
sort(vertice_names.begin(), vertice_names.end(), less<int>());
printf("Adj and value matrix\n");
printf(" ");
for(int i = 0; i<number_of_vertices; i++)
{
printf("%3d",vertice_names.at(i));
}
printf("\n");
for (int i = 0; i<number_of_vertices; i++)
{
printf("%3d ", vertice_names.at(i));
for (int j = 0; j <number_of_vertices; j++)
{
if (adj_matrix[i][j])
{
printf("%3d",val_matrix[i][j]);
}
else
{
printf(" ");
}
}
printf("\n");
}
return 0;
}
format of the .txt file:
first line : number of vertices
second : number of arcs
the other lines : Inital Arc Final Arc Value
3
4
0 1 0
1 0 12
1 2 25
2 0 6
By the way, if someone have a better idea to check if a graph has a cycle let me know
Best regards
Looks to me like you are stepping out of bounds in the Cycle function:
for(int i=0;i<number_of_vertices;i++)
{
for(int j=0;j<number_of_vertices;j++)
{
adj[i][j] = adj_matrix[i+1][j+1]; // i + 1 and j + 1 go out of bounds
}
}
Suppose number_of_vertices is 3. Then the index of the last element is 2. When i = 2, then i + 1 = 3. Out of bounds.

Program crashed after end of scope

I was confused from this following codes, it's creating crash that I fully don't understand.
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
struct Store
{
int pos;
char character;
};
vector<struct Store> v_store;
void swap_inside_vector(vector<struct Store> &v_store, int a, int b)
{
struct Store tmp = v_store[b];
v_store[b] = v_store[a];
v_store[a] = tmp;
}
int find_inside_vector(vector<struct Store> &v_store, int pos)
{
for(int i = 0; i < v_store.size(); i++)
{
if(v_store[i].pos == pos)
return i;
}
return -1;
}
void swap_most_right_to_most_left(vector<struct Store> &v_store)
{
struct Store tmp = v_store[v_store.size() - 1];
for(int i = v_store.size(); i > 0; i--)
{
v_store[i] = v_store[i-1];
}
v_store[0] = tmp;
}
void print_char_inside_vector(vector<struct Store> &v) // used for debugging
{
for(int i = 0; i < v.size(); i++)
{
printf("%C", v[i].character);
}
}
int check_vector_original_state(vector<struct Store> &v_store)
{
for(int i = 1; i <= v_store.size(); i++)
{
if(v_store[i-1].pos != i)
return 0;
}
return 1;
}
int main()
{
int n;
char input_str[100];
for(int q = 1; scanf("\n%d", &n), n; q++)
{
scanf("%s", input_str);
vector<struct Store> original_store, tmp_origin_store, v_store;
vector<vector<struct Store> > store_vector;
original_store.clear();
tmp_origin_store.clear();
v_store.clear();
store_vector.clear();
for(int i = 1; i <= strlen(input_str); i++)
{
struct Store s = {.pos = i, .character = input_str[i-1]};
original_store.push_back(s);
}
tmp_origin_store = original_store;
v_store = tmp_origin_store;
for(int i = 1, current_pos = 0; i <= n; i++, current_pos++)
{
int vector_index = find_inside_vector(v_store, tmp_origin_store[current_pos].pos);
//printf("Processing -> [%d], Current Pos -> [%d]\n", i, current_pos);
for(int z = 0; z < (current_pos + 1); z++)
{
if(vector_index == (v_store.size() - 1))
{
swap_most_right_to_most_left(v_store);
vector_index = 0;
}
else
{
swap_inside_vector(v_store, vector_index, vector_index + 1);
vector_index++;
}
//print_char_inside_vector(v_store);
//puts("");
}
//puts("");
store_vector.push_back(v_store);
if(check_vector_original_state(v_store))
{
store_vector.push_back(v_store);
break;
}
if(current_pos == (v_store.size() - 1))
{
tmp_origin_store = v_store;
current_pos = -1;
}
}
// debugging
/*for(int x = 0; x < store_vector.size(); x++)
{
printf("[%d] -> ", x + 1);
print_char_inside_vector(store_vector[x]);
puts("");
}*/
int target_pos;
if(store_vector.size() < n)
{
target_pos = n % store_vector.size();
}
else
{
target_pos = store_vector.size();
}
if(target_pos == 0)
{
printf("%d. ", q);
print_char_inside_vector(store_vector[0]);
puts("");
}
else
{
printf("%d. ", q);
print_char_inside_vector(store_vector[target_pos - 1]);
puts("");
}
}
}
What this program does is accepting input from STDIN, process it, and output it on STDOUT.
My expecting input is
3 ABCD
13 ACM
3 DAEQD
4 FAEQS
Expected output is
1. CABD
2. CAM
3. DAQDE
4. FQASE
My problem is, after inputing fourth input into STDIN, and after output is being shown, crash occured.
C:\Study>h.exe
3 ABCD
1. CABD
13 ACM
2. CAM
3 DAEQD
3. DAQDE
4 FAEQS
4. FQASE
0 [main] h 9092 cygwin_exception::open_stackdumpfile: Dumping stack trace to h.exe.stackdump
From my observation, I think the problem is at the vector, but it's just a guess.
Your code didn't compile :
//struct Store s = { .pos = i, .character = input_str[i - 1] }; // syntax not recongnized
Store s = { i, input_str[i - 1] }; // replaced with this.
After fixing this, the debugging immediatly identified an out of bound problem on a vector, which could lead to memory corruption issue. It's in swap_most_right_to_most_left():
for (int i = v_store.size(); i > 0; i--) { // you start with i=v_store.size()
v_store[i] = v_store[i - 1]; // and you immediately get out of bounds !
}
If you correct this instruction to :
for (int i = v_store.size()-1; i > 0; i--) {
v_store[i] = v_store[i - 1];
}
you'll get the expected output for the given input.

What is wrong with my binary search algorithm?

I have written a binary search like following. When I try to find 10, it's not showing me the result. What am I missing??
// BinarySearch.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
void BinarySearch(int arr[],int value);
int * insertionshot(int arr[]);
int _tmain(int argc, _TCHAR* argv[])
{
int arr[10] = {1,2,3,10,5,9,6,8,7,4};
int value;
cin >> value ;
static int *ptr;// = new int[10];
ptr = insertionshot(arr);
BinarySearch(ptr,value);
return 0;
}
int * insertionshot(int arr[])
{
int ar[10];
for(int i =0;i < 10; i++)
{
ar[i] = arr[i];
}
int arrlength = sizeof(ar)/sizeof(ar[0]);
for(int a = 1; a <= arrlength -1 ;a++)
{
int b = a;
while(b > 0 && ar[b] < ar[b-1])
{
int temp;
temp = ar[b-1];
ar[b-1] = ar[b];
ar[b] = temp;
b--;
}
}
return ar;
}
void BinarySearch( int a[],int value)
{
int min,max,middle;
min = 0;
int ar[10];
for(int i =0;i < 10; i++)
{
ar[i] = a[i];
}
//printf("size of array = %d",sizeof(arr));
max = (sizeof(ar)/sizeof(ar[0]) -1);
middle = (min+max)/2;
while(min <= max)
{
if(ar[middle] == value)
{
cout << "The value found" << ar[middle];
break;
}
else if(ar[middle] < value)
{
min = middle +1;
}
else if(ar[middle] > value)
{
max = middle-1;
}
middle = (min+max)/2;
}
}
Finally i made it work,I think this code does not have any problem.This could help any one
// BinarySearch.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
void BinarySearch(int arr[],int value);
int * insertionshot(int arr[],int);
int _tmain(int argc, _TCHAR* argv[])
{
int arr[10] = {1,2,3,10,5,9,6,8,7,4};
int * arr1 = new int[10];
for(int i = 0;i< sizeof(arr)/sizeof(arr[0]);i++)
{
arr1[i] = arr[i];
}
int value;
cin >> value ;
int *ptr = new int[10];
ptr = insertionshot(arr1,10); // address of sorted array will be returned.
BinarySearch(ptr,value);
arr1 = 0;
ptr =0;
delete arr1;
delete ptr;
return 0;
}
int * insertionshot(int arr1[],int n)
{
for(int a = 1; a <= n -1 ;a++)
{
int b = a;
while(b > 0 && arr1[b] < arr1[b-1])
{
int temp;
temp = arr1[b-1];
arr1[b-1] = arr1[b];
arr1[b] = temp;
b--;
}
}
return arr1;
}
void BinarySearch( int a[],int value)
{
int min,max,middle;
min = 0;
int ar[10];
for(int i =0;i < 10; i++)
{
ar[i] = a[i];
}
max = (sizeof(ar)/sizeof(ar[0]) -1);
middle = (min+max)/2;
while(min <= max)
{
if(ar[middle] == value)
{
cout << "The value found" << ar[middle];
break;
}
else if(ar[middle] < value)
{
min = middle +1;
}
else if(ar[middle] > value)
{
max = middle-1;
}
middle = (min+max)/2;
}
}
You're missing the most important part of a binary search: The collection you search in must be sorted.
For binary search, the array should be arranged in ascending or descending order.