Where is the origin of the Segmentation fault - c++

This piece of code is supposed to go through a column of a vector of this format: -23 ##.###(where '-' is the beginning of the column and the last # is the end), if you're not aware of the concept of a nanogram, the first number says there are 2 hashes, and the second says there are 3 hashes, there is a minimum requirement of at least one dot(.) or one "whitespace" between each set of hashes(blackspaces). All i want this code to do is to check if the hashes correspond to the numbers for the columns first, but for some reason the input vector;
\[\["-","-","-","-","-","-","-","-"\],\["-","-","-","2","2","1","-","1"\],\["-","-","-","2","1","1","3","
3"\],\["-","3","1","#","#","#",".","#"\],\["-","-","2","#","#",".",".","."\],\["-","-","2",".",".",".","#","#"\],\["-","1","2","#",".",".","#","#"\],\["-","-","5","#","#","#","#","#"\]\]
gives the "segmentation fault" error and codesignal's IDE doesn't much more detail than that.
#include <iostream>
#include <vector>
using namespace std;
bool countSharpsVertically(vector<vector<string>> & referenceVectorOfVectorStrings, int column, int distance) {
for (int i{}, j{distance}; j<referenceVectorOfVectorStrings.size()/*i < distance*/; i++) {
while (referenceVectorOfVectorStrings[i][column]=="-") // might want to check if there are no numbers idk how annoying these edge cases are going to be
i++;
// cout << (referenceVectorOfVectorStrings[j][column])<< " ";j++;
while (referenceVectorOfVectorStrings[j][column]==".")j++;
for ( int spaces{}; spaces<stoi(referenceVectorOfVectorStrings[i][column]); j++, spaces++){
if (referenceVectorOfVectorStrings[j][column]!="#")return false;
}
if (referenceVectorOfVectorStrings[j][column]!=".")return false;
if (i<distance-1&&j>=referenceVectorOfVectorStrings.size())return 0;
// cout << referenceVectorOfVectorStrings[j++][column] << " ";
}
cout << endl;
return true;
}
bool solution(int size, vector<vector<string>> nonogramField) {
int distance=(size + 1) / 2;
//check down
// cout << distance;
for (int i{distance}; i < nonogramField.size(); i++ ) {
if (!countSharpsVertically(nonogramField, i, distance)) return 0;
}
//check left
return true;
}
int main() {
vector<vector<string>> nonogramField = {{"-","-","-","-","-","-","-","-"},
{"-","-","-","2","2","1","-","1"},
{"-","-","-","2","1","1","3","3"},
{"-","3","1","#","#","#",".","#"},
{"-","-","2","#","#",".",".","."},
{"-","-","2",".",".",".","#","#"},
{"-","1","2","#",".",".","#","#"},
{"-","-","5","#","#","#","#","#"}};
cout << solution(5, nonogramField);
return 0;
}
All my initial suspicions for the origin of the segmentation fault were wrong, please where is the error coming from.

Related

Trying to make a program that automatically sorts an array before using binary searching

I'm trying to make a program that asks the user to input a set of 10 numbers before asking them to select a number from the list. it would first automatically sort the ten numbers before being placed in a binary searching function.
Here's the code I wrote.
#include <iostream>
using namespace std;
int searchbinary(int arr[], int left, int right, int x){
while (left <= right){
int mid = left+(right-left)/2;
if (arr[mid]==x){
return mid;
}
else if (arr[mid]<1){
left = mid + 1;
}
else{
right = mid -1;
}
}
return -1;
}
int main(){
int num;
int darr[10];
int output;
int temp;
cout << "Enter 10 Numbers: " << endl;
for (int i=0; i<10; i++){
cin >> darr[i];
}
for (int i=0;i<10;i++){
for (int j=i+1;j<10;j++){
if (darr[i]>darr[j]){
temp = darr[i];
darr[i] = darr[j];
darr[j] = temp;
}
}
}
cout << "Enter a number from list: ";
cin >> num;
output = searchbinary(darr, 0, 9, num);
if (output ==-1){
cout << "Match not Found";
}
else {
cout << "Match Found in Position " << output;
}
return 0;
}
It works fine when I do it separately, but combining the two seems to cause an issue. Any suggestions?
Well, there seems to be a problem with your Binary Search. In the else if condition you wrote arr[mid] < 1 whereas it should have been arr[mid] < x because you are trying to find x not 1. Bellow is the code that should work:
#include <iostream>
using namespace std;
//binary search
int searchbinary(int arr[], int left, int right, int x){
while (left <= right){
int mid = (right+left)/2;//this formula is better than the one you used, it has the same results though
if (arr[mid] == x){
return mid;
}
else if (arr[mid] < x) {//here was your mistake,it is x not 1
left = mid + 1;
}
else{
right = mid -1;
}
}
return -1;
}
int main(){
int num;
int darr[10];
int output;
int temp;
cout << "Enter 10 Numbers: " << endl;
//input
for (int i=0; i<10; i++){
cin >> darr[i];
}
//sorting
for (int i=0;i<10;i++) {
for (int j=i+1;j<10;j++) {
if (darr[i]>darr[j]) {
temp = darr[i];
darr[i] = darr[j];
darr[j] = temp;
}
}
}
cout << "Enter a number from list: ";
cin >> num;
output = searchbinary(darr, 0, 9, num);//searching
//output
if (output == -1){
cout << "Match not Found";
}
else {
cout << "Match Found in Position " << output;
}
return 0;
}
If you fix that issue then your code should work but I would like to point some things out:
It is better not to hardcode numbers, like when you write 10 as a limit to all for loops. It would be better to save 10 in a variable or use darr.length().
Instead of using your own Sort you could have used the built-in sort that the algorithm library provides like this sort(darr, darr+10). In this case it was only with 10 elements but bear in mind that if you ever find yourself trying to solve the same problem with array sizes up to a million or more, the sort you implemented(it is called Bubble sort), would take up to much time, whereas std::sort would be able to do it faster as it has been optimised.
In this problem first sorting the array and then using Binary Search on top of it takes more time than performing Linear Search on the unsorted array. Generally, when searching once for a value on an unsorted array, first sorting it and then using Binary Search takes up more time than just doing Linear Search no matter the size of the array. However, if you wanted to to use the array in the future multiple times then your approach could prove to be faster.
These are all small improvements that you could make to your code but I am guessing this is done for educational purposes that is why you didn't do some of them.

C++11 - Error in calculating mode in a vector of numbers

I'm working on a program that, given a list of values (doubles) from an input file, sorts them in ascending order and calculates the mode, and print the result in an output file. This is what I came up with so far.
What it should do is assign the mode to the xth element of the vector, the one that produces the greater value for current, but when I run this program the mode is always equal to the last element of the vector.
I just can't figure out what mistake I'm doing, because in my mind it seems perfectly logical.
Any help is greatly appreciated.
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <fstream>
using namespace std;
int main()
{
ifstream iFile("inp.txt");
if(!iFile)
{
cout << "Error input!" << endl;
return -1;
}
ofstream oFile("out.txt");
if(!oFile)
{
cout << "Error output!" << endl;
return -1;
}
double data;
vector<double> list;
while(iFile >> data)
{
list.push_back(data); //put the elements in a vector
sort(list.begin(), list.end()); //and sort them in ascending order
}
for(int m = 0; m < list.size(); ++m) //this is just
{ //to verify
oFile << list[m] << endl; //that the elements
} //are listed in order
int current = 0;
int previous = 0;
int mode = 0;
for(int x = 0; x < list.size(); ++x) //select an element of the vector
{
for(int y = 0; y < list.size(); ++y) //match it against all the other elements of the vector
{
if(list[x] == list[y]) //if they're of equal value
{
++current; //add 1 to variable "current"
}
}
if(current > previous) //if "current" > "previous"
{
mode = list[x]; //set the element "x" (from the first for) of the vector "list" to be the new mode
current = previous; //and set current to be the new previous
}
current = 0; //reset current to 0
}
oFile << "\nmode: " << mode << endl; //output "mode"
return 0;
}
Try with
previous = current;
instead of
current = previous;
in the last if, or previous is ever zero and the last x (matching with itself when y is equal to x) generate a current greater than previous (that is zero).
OT: look at this while
while(iFile >> data)
{
list.push_back(data); //put the elements in a vector
sort(list.begin(), list.end()); //and sort them in ascending order
}
There is no need to sort the vector after every single insertion. I suggest you to add in list all the content of the input file and, after, sort the vector. Only one time, only after the last insertion.
Something like
while(iFile >> data)
{
list.push_back(data); //put the elements in a vector
}
sort(list.begin(), list.end()); //and sort them only one time

How to make a while loop till there is something to be readen c++

I know that you probably gona again vote me down, I really don't understand this but im really stuck at something and cant figure it out , there is no such information anywhere in the web , neither in my book for the course, so I have this assignment where I need make 2 sums of containers where the difference between 2 sums is the lowest , so the program is done is working perfectly calculated everything however , in my assignment:
The user enter on one row unkwonw length numbers so after that I do all kind of sums between them and find the one with lowest difference between.
Ok but the way I wrote the code I use one while(true) so that to work with infinity testcases(as from assignment) and in this while(true) I have another while(cin>>(SOMEINT)) loop and push it back in a vector , and after it reads new line it just break the wile and continue with the calculation.
However in our test software this one give runtime error since after finding some cases then it start print infinity 0 0 since there is nothing to enter but the while(true) just continues.
I mean I just want to make it that way that the while is till user enters something , for instance you enter 30 50 90 it will return 80 90 , then wiat for another entry and so on.
CODE:
#include <iostream>
#include <string>
#include<vector>
#include <sstream>
#include <cmath>
#include <string.h>
#include <stdio.h>
#include <climits>
using namespace std;
const int length = 17000;
int power(int x){
int sum =2;
for(int i = 0;i<x;i++) {
sum *= 2;
}
return sum;
}
bool ison(int i,int x)
{
if((i>>x) & 1)return true;
return false;
}
int main()
{
while(true){
vector<int> Vec;
int cur = 0;
while (cin >> cur) {
Vec.push_back(cur);
if (cin.get() == '\n') {
break;
}
}
int * sumOfarr1 = new int[length];
int * sumOfarr2 = new int[length];
for(int i = 0; i<length;i++){
sumOfarr1[i] = 0;
}
for(int i = 0; i<length;i++){
sumOfarr2[i] = 0;
}
int index=0;
for(int i=1;i<length;i++)
{
for(int j=0;j<Vec.size();j++)
{
if(ison(i,j))
{
sumOfarr1[index]+=Vec[j];
}
else
{
sumOfarr2[index]+=Vec[j];
}
}index++;
}
int ans=INT_MAX;
int ii;
for(int i=0;i<index;i++)
{
if(abs(sumOfarr1[i]-sumOfarr2[i])<ans)
{
ii=i;
ans=abs(sumOfarr1[i]-sumOfarr2[i]);
}
}
if(sumOfarr1[ii]<sumOfarr2[ii]){
cout << sumOfarr1[ii] << " " << sumOfarr2[ii];
}
else{
cout << sumOfarr2[ii] << " " << sumOfarr1[ii];
}
cout << endl;
delete[] sumOfarr1;
delete[] sumOfarr2;
Vec.clear();
}
return 0;
}
Yes I found the solution just using getline and stringstream.
aka this
vector<int> Vec;
string line;
while(getline( cin, line ))
{
istringstream iss( line );
int number;
while( iss >> number )
Vec.push_back(number);
}

Cygwin Error When Running Mastermind Program

I am trying to write a program for my programming class that successfully runs a game of mastermind with numbers 1-6 as inputs instead of colors. When I try to test the program as is I get the message
" 0 [main] Lab16 9828 cygwin_exception::open_stackdumpfile: Dumping stack trace to Lab16.exe.stackdump"
Commenting out sections of the code does not seem to help much. I am quite the noobie to all of this so any lessons learned are appreciated.
Any help/suggestions are greatly appreciated! Thank you for reading my question!
/** INCLUDE FILES ***************************************************/
#include <iostream> // input output commands: cout & cin
#include <iomanip>
#include <vector>
#include <cmath>
#include <cstdlib>
using namespace std;
/** FUNCTION PROTOTYPES**********************************************/
void GetPatterns(vector <int> &x); // Gets user pattern
void CreateSolution(vector <int> &y); // Creates the right pattern before user input
bool SolutionCalc(vector <int> x, vector <int> y); // Detects how many guesses are correct and or in the right place, returns bool value to main()
/** MAIN FUNCTION ***************************************************/
int main()
{
/** VARIABLE DECLARATION ****************************************/
bool solution;
vector <int> UserPattern;
vector <int> RealPattern;
srand(time(0));
/** FUNCTION CALLS***********************************************/
CreateSolution(RealPattern);
do
{
GetPatterns(UserPattern);
solution = SolutionCalc(UserPattern,RealPattern);
}while(solution == false);
cout << "Correct!" << endl;
cout << "You are a Mastermind!" << endl;
return 0;
}
/** FUNCTIONS *******************************************************/
void GetPatterns(vector <int> &x)
{
cout << "Welcome to Mastermind." << endl;
cout << endl;
cout << "Please enter your four numerical guesses(space separated, numbers 1-6): ";
for (int i = 0; i < 4; i++) // 4 size vector array for user input
{
cin >> x[i];
}
cout << endl;
}
void CreateSolution(vector <int> &y)
{
for(int e = 0; e < 4; e++) // 4 size vector array for solution
{
y[e] = rand()%6+1;
}
cout << endl;
}
bool SolutionCalc(vector <int> x, vector <int> y) // Z is the bool to check if the solution is solved or not
{
int RightNum = 0, RightPlace = 0;
bool IsSolution;
for (int i = 0; i < 4; i++)
{
if (x[i] == y[i])
{
RightPlace++;
}
if ((x[i] != y[i]))
{
if(x[i] == y[0] || x[i] == y[1] || x[i] == y[2] || x[i] == y[3])
{
RightNum++;
}
}
}
if (RightNum < 4)
{
cout << "You have " << RightNum << " correct number(s) and " << RightPlace << " correct locations(s)." << endl;
IsSolution = false;
}
else if (RightNum == 4)
{
IsSolution = true;
}
return IsSolution;
}
You're assuming that all your vectors have four elements, when you've default-initialized them. Default-initialization for vectors produces vectors with zero elements, so when you access the first through fourth elements of the vectors, you exceed the bounds of the vector.
This is a short example of what I'm talking about:
std::vector<int> myvector;
myvector[1] = 3; // oh no!
You have three options for fixing this. Either you can predefine the size of the vector:
std::vector<int> myvector(4);
myvector[1] = 3; // ok
or you can change it to the appropriate size while you're populating it:
std::vector<int> myvector; // elsewhere
myvector.resize(4);
myvector[1] = 3; // okay
or you can dynamically adjust the size of the array when you're populating it:
std::vector<int> myvector; // elsewhere
for(size_t index = 0; index < 4; ++index){
myvector.push_back(someNumber); // also okay
}
With all the syntaxes, once you've populated your vector, you can access elements the way you expect, with operator[]. Just make sure not to exceed the bounds of the vector! You can check how big a vector is with a call to size like so: myvector.size();

Solving the Josephus Problem using a vector

EDIT: I seem to have sorted out the errors, at the very least, and have updated the code. However, the math still doesn't seem to be working out. Any ideas?
In short, I'm trying to write a program in C++ that will prompt the user for the number of people in the initial circle, and then tell them in which position they should stand in order to survive if k (the number of people counted to before being executed) = 3.
I've got what I think is the right idea, but I get the error "Debug Assertion Failed" and "Expression: vector erase iterator outside range" if I input k as anything other than 1, 2, or 5.
// ConsoleApplication2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int n;//size of the circle
vector <int> circle; //the circle itself
//ask for how many people are in the circle
cin >> n;
//fill the circle with 1,2,3...n
for (int idx = 0; idx < n; idx++)
{
circle.push_back (idx+1);
}
//cout << "The size of the circle is " << circle.size() << ".\nThe highest number is " << circle[n-1] << "."; //test to make sure numbers are being assigned properly to each vector element
for (int count = 0, idx = 0; circle.size() > 1; idx++,count++)
{
//if the position (idx) is greater than the size of the circle, go back to the beginning of the circle and start counting again
if (idx >= circle.size())
{
idx = 0;
}
//every time the counter reaches three, that person is executed
if (count == 3)
{
circle.erase (circle.begin()+(idx));
count = 0;
}
}
cout << "The place to stand to win the hand is position #" << circle.front() << ".\n";
return 0;
}
You only check for if (idx > circle.size()) and then go ahead and call circle.erase (circle.begin()+(idx));. This call isn't safe when idx == circle.size().
#Pradhan already gave you the solution to your original error (idx >= circle.size() instead of idx >= circle.size().
For why the result is still not correct:
When you erase an element, you have to adjust your index to compensate for it (subtract 1). Otherwise the index corresponds to the next element in the vector, so effectively you are always executing every 4th person not every 3rd.
Here is my version of the code:
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
int main(){
int n;
cin >> n;
//fill the circle with 1,2,3...n
vector <int> circle(n);
std::iota(std::begin(circle), std::end(circle),1);
int idx = -1;
while (circle.size() > 1) {
//advance by threee
idx = (idx + 3) % circle.size();
//execute Person
circle.erase(circle.begin() + (idx));
//readjust to compensate for missing element
--idx;
}
cout << "The place to stand to win the hand is position #" << circle.front() << ".\n";
}
of course, you can rewrite the loop to
int idx = 0;
while (circle.size() > 1) {
//advance by three
idx = (idx + 2) % circle.size();
//execute Person
circle.erase(circle.begin() + (idx));
}