Why this code waits for user to input 10 integers when size of array input by user is 8 ? It gives segmentation fault when 10 integers are used.`
#include <iostream>
using namespace std;
int main()
{
int x, a[x];
cout << "enter the size of array" << endl;
cin >> x;
cout << "enter the elements" << endl;
for (int j = 0; j < x; j++)
cin >> a[j];
for (int i = 1; i < x; i++) {
for (int k = 0; k < i; k++) {
if (a[i] < a[k])
swap(a[i], a[k]);
else
continue;
}
}
for (int m = 0; m < x; m++)
cout << a[m];
}
The issue is in these lines:
int x, a[x];
cout<<"enter the size of array"<<endl;
cin>>x;
Here, when you declare the array a, it sizes it using the value stored in x. However, at this point, you haven't given x a value, so you get an array of garbage size. Reading in x later on doesn't retroactively resize the array (the same way that changing a variable at one point doesn't retroactively change other variables whose value is based on it), so the array size doesn't match the read value. Plus, if the array is too big, you might get a stack overflow before you even get to the spot where you read things!
To fix this, consider using something like std::vector rather than raw arrays. (As a note, variable-length arrays aren't supported in C++, so using std::vector would be more portable.)
Related
c++
When printing to console, if function execution is sequential it would seem logical the ordered array would be printed after calling insertionSort, however order list does not print until next loop. Any help would be appreciated.
#include <stdio.h>
#include <iostream>
#include <array>
using namespace std;
void insertionSort(int* array, int size) {
for (int i = 1; i < size; i++) {
int key = i - 1;
while (i > 0 && array[key] > array[i] ) {
int tmp = array[i];
array[i] = array[key];
array[key] = tmp;
i -= 1;
key -= 1;
}
}
}
const int ARRAY_MAXSIZE = 5;
int main(void) {
int *array = (int*)calloc(ARRAY_MAXSIZE, sizeof(int));
int input;
cout << "Enter 5 digits\n";
for (int size=0; size < ARRAY_MAXSIZE; size++) {
cout << size << " index ";
cin >> input;
array[size] = input;
insertionSort(array, size);
for (int j=0; j <= size; j++) {
cout << array[j];
}
cout << '\n';
}
}
Console Entry
This is a classic off-by-one error. Your insertionSort expects you to pass the number of elements to sort via the parameter size. But your main loop is always holding a value that is one less than the size immediately after adding an element.
I want to say that bugs like this are easily discovered by stepping through your program's execution with a debugger. If you don't know how to use a debugger, start learning now. It is one of the most important tools used by developers.
Anyway, the quick fix is to change your function call to:
insertionSort(array, size + 1);
However, as Paul McKenzie pointed out in comments, it's a bit crazy to do this every time you add a new element because your function sorts an entire unsorted array. Your array is always nearly sorted except for the last element. You only need to call that function once after your input loop is done:
// Read unsorted data
for (int size = 0; size < ARRAY_MAXSIZE; size++) {
cout << size << " index ";
cin >> input;
array[size] = input;
}
// Sort everything
insertionSort(array, ARRAY_MAXSIZE);
// Output
for (int j = 0; j < ARRAY_MAXSIZE; j++) {
cout << array[j];
}
cout << '\n';
But if you want every insertion to result in a sorted array, you can "slide" each new value into place after inserting it. It's similar to a single iteration of your insertion-sort:
// Sort the last element into the correct position
for (int i = size; i >= 1 && array[i] > array[i - 1]; i--)
{
std::swap(array[i], array[i - 1]);
}
Even better, you don't need to swap all those values. You simply read the value, then shuffle the array contents over to make room, then stick it in the right spot:
// Read next value
cin >> input;
// Shuffle elements to make room for new value
int newPos = size;
while (newPos > 0 && array[newPos - 1] > input) {
array[newPos] - array[newPos - 1];
newPos--;
}
// Add the new value
array[newPos] = input;
Task
Given n gold bars, find the maximum weight of gold that fits into bag of capacity W
Input
first line contains the capacity W of the knapsack and the number n of bars of gold. The next line contains n integers
Output
The max weight of gold that fits into a knapsack of capacity W.
Constraints
1 <= W <= 10000; 1<= n <= 300; 0 <= w0, w1, w2, ... , w(n-1) <= 100000
Code
#include <iostream>
#include <vector>
using std::vector;
int optimal_weight(int W, vector<int> w) {
int n = w.size() + 1;
int wt = W + 1;
int array [n][wt];
int val = 0;
for(int i = 0; i < wt; i++) array [0][i] = 0;
for(int i = 0; i < n; i++) array [i][0] = 0;
for(int i = 1; i< n; i++) {
for(int j = 1; j < wt; j++ ){
array[i][j] = array [i-1][j];
if (w[i-1] <= j) {
val = array[i-1][j - w[i-1]] + w[i-1];
if(array[i][j] < val) array[i][j] = val;
}
}
}
//printing the grid
// for(int i=0; i < n; i++) {
// for(int j=0; j < wt; j++) {
// cout<<array[i][j]<<" ";
// }
// cout<<endl;
// }
// cout<<endl;
return array [n-1][wt-1];
}
int main() {
int n, W;
std::cin >> W >> n;
vector<int> w(n);
for (int i = 0; i < n; i++) {
std::cin >> w[i];
}
std::cout << optimal_weight(W, w) << '\n';
}
The above code works fine for smaller inputs, but gives an unknown signal 11 error on the platform I wish to submit to. My best guess is of a possible segmentation fault, but I have been unable to debug it since quite some time now. Any help is much appreciated!
First note that your code doesn't work. That is, it doesn't compile when you adhere strictly to the C++ language standard, as C++ does not support variable-length arrays. (as noted by #Evg in a comment; some compilers offer this as an extension.)
The main reason for excluding those from C++ is probably why you're experiencing issues for larger problem sizes: the danger of stack overflows, the namesake of this website (as noted by #huseyinturgulbuyukisik in a comment). Variable-length arrays are allocated on the stack, whose size is limited. When you exceed it, you might attempt to write to a segment of memory that is not allocated to your process, triggering Linux signal 11, also known as SIGSEGV - the segmentation violation signal.
Instead of stack-based allocation, you should allocate your memory on the heap. A straightforward way to do so would be using the std::vector container (whose default allocator does indeed allocate on the heap). Thus, you would write:
std::vector<int> vec(n * wt);
and instead of array[i][j] you'd use vec[i * wt + j].
Now, this is not as convenient as using array[x][y]; for the extra convenience you can, for example, write a helper lambda, to access individual elements, e.g.
auto array_element = [&vec, wt](int x, int y) { return vec[x * wt + y]; }
with this lambda function available, you can now write statements such as array_element(i,j) = array_element(i-1,j);
or use a multi-dimensional container (std::vector<std::vector<int>> would work but it's ugly and wasteful IMHO; unfortunately, the standard library doesn't have a single-allocation multi-dimensional equivalent of that).
Other suggestions, not regarding a solution to your signal 11 issue:
Use more descriptive variable names, e.g. weight instead of wt and capacity instead of W. I'd also considersub_solutions_table or solutions_table instead of array, and might also rename i and j according to the semantics of the dynamic solution table.
You never actually need more than 2 rows of the solutions table; why not just allocate one row for the current iteration and one row for the previous iteration, and have appropriate pointers switch between them?
Replace
vector< vector< int> > k(n + 1,vector< int>(W + 1));
with
int array[n][w];
i used to code in javascript, but my new school force me to learn c++.
Im kind new in this language, and here's the problem:
In javascript i can write such a code:
for(let i = 0; i < 10; i++){
var variable[i] = i+3;
}
for(let j = 0; j < 10; j++){
console.log(variable[j]);
}
You may say 'Why don't you just write the code into 1 for loop', but that's only example.
And now i'm trying to rewrite above code to cpp:
int n,k,w;
cin>>n>>k;
for(int i = 0; i < n; i++){
int w[i];
cin>>w[i];
}
//some code here
for(int i = 0; i < n; i++){
cout<<w[i];
}
And here's the question. How can i cout all variables w with index i, cause im getting an error [Error] invalid types 'int[int]' for array subscript.
What you probably want is:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec;
int size = 0;
std::cin >> size;
for(int i = 0; i < size; i++){
int number = 0;
std::cin >> number;
vec.push_back(number);
}
for(int i : vec){
std::cout << i << " ";
}
}
std::vector<int> is a class designed to provide an interface to resizable array. The push_back() function appends the vector with given argument.
The last loop, which is called a ranged-based for(), is used to print all elements of the vector. You can replace it with plain old for() loop with indexing, since std::vector supports operator [], but if ranged-based approach is sufficient, it should be preferred.
EDIT: I don't know JavaScript, but I assume (from your example) that variables declared inside loops are visible everywhere. This is not the case in C++. Variables' visibility is dependent on the scope they are declared in. If you want your list/array/vector/any other container to be visible to those two for() loops, you have to declare it outside them - like in my example above.
EDIT2: While you should almost always use std::vector for such tasks, one could argue that they want to disable resizing the container. In this case, we are left with simple dynamic allocation. We reach for <memory> library, since we shouldn't manage it ourselves:
#include <iostream>
#include <memory>
int main() {
int size = 0;
std::cin >> size;
auto arr = std::make_unique<int[]>(size);
for(int i = 0; i < size; i++){
int number = 0;
std::cin >> number;
arr[i] = number;
}
for(int i = 0; i < size; i++){
std::cout << arr[i] << " ";
}
}
For auto, either read here or imagine that it's just a magic type that is (almost always) correct. It's like var in Python or JavaScript (but later on its type cannot be changed).
For std::unique_ptr<T[]>, either read here or imagine that it's just a dynamically allocated array that automatically delete[]s itself. If you did not learn about dynamic allocation yet, simply ignore what that means and wait until it's introduced.
Notice that we also got rid of the ranged-based for() loop. Unfortunately, it does not work with plain, dynamically allocated arrays.
Not all compilers support VLA so stick to the Standards; always specify a constant size for arrays. If you need some dynamically changed size then consider using another type of containers like: std::vector.
Also why you re-declared int w inside the for loop? It is local to for loop and changes to it won't affect the outer one.
You get a compile time error in the second loop that complains that w is not an array. To solve it make int w[] outer and on top of the two loops.
int n, k;
cin >> n >> k;
int w[n];
for(int i = 0; i < n; i++)
cin >> w[i];
//some code here
for(int i = 0; i < n; i++)
cout << w[i];
The alternative to VAL use std::vector:
std::vector<int> w;
int n, k;
std::cin >> n;
for(int i(0); i!= n; ++i){
std::cin >> k;
w.push_back(k);
}
for(auto i(0); i != w.length(); ++i)
std::cout << w[i] << ", ";
as the title says I'm attempting to compare elements in an array. My intent is to have the user enter 3 integers into the program, thereafter it should increment through this array comparing the the 1st number to the 2nd, and so forth and swapping the element's from order of lowest to highest.
My issue currently is that it will swap the first and second elements but the third causes an integer overflow due to me comparing and assigning an integer in an index higher than the initialized array can hold.
I'm currently drawing a blank as to how I could still compare these numbers in this manner without causing it to overflow.
A hint or perhaps a whole different perspective would be appreciated.
#include "E:/My Documents/Visual Studio 2017/std_lib_facilities.h"
int main()
{
cout << "Enter three integers: \n";
int numbersArray[3];
int temp = 0; //This lets us hold our integers temporarily so we can swap them around in the array
//This enters integers as elements in the array
for (int i = 0; i < 3; i++)
{
cin >> numbersArray[i];
}
//This should swap the elements from smallest to greatest
for (int i = 0; i = 3; i++)
{
if (numbersArray[i] > numbersArray[i+1])
temp = numbersArray[i];
numbersArray[i] = numbersArray[i+1];
numbersArray[i+1] = temp;
//swap(numbersArray[i], numbersArray[++i]);
}
//This prints the index's containing the elements in the array
for (int i = 0; i < 3; i++)
{
cout << numbersArray[i] << ' ';
}
cout << endl;
keep_window_open();
return 0;
}
You will need to modify this to suit your needs, but this should get you on the right track. One important thing to investigate is how you decided to sort the elements. Your sorting needs to be looped, otherwise, you won't necessarily sort the entire array (depending on your inputs).
#include <iostream>
using namespace std;
int main()
{
cout << "Enter three integers: \n";
int numbersArray[3];
int temp = 0; //This lets us hold our integers temporarily so we can swap them around in the array
//This enters integers as elements in the array
for (int i = 0; i < 3; i++)
{
cin >> numbersArray[i];
}
for(int loop = 0; loop <3; loop++){
//This should swap the elements from smallest to greatest
for (int i = 0; i < 2; i++)
{
if (numbersArray[i] > numbersArray[i+1]){
temp = numbersArray[i];
numbersArray[i] = numbersArray[i+1];
numbersArray[i+1] = temp;
}
//swap(numbersArray[i], numbersArray[++i]);
}
}
//This prints the index's containing the elements in the array
for (int i = 0; i < 3; i++)
{
cout << numbersArray[i] << ' ';
}
cout << endl;
return 0;
}
I want to make a program that lets the user insert some numbers to the array and the print it out afterwards. Problem is when I try to do that (lets say the size of my array is 100) then:
What it should do: Inserted- 1,2,3,4,5 -> should print 1,2,3,4,5
But instead it prints -> 1,2,3,4,5,0,0,0,0,0,0, .... up to the size of my array.
Is there any way I can get rid of those zeros?
Code:
int SIZE = 100;
int main()
{
int *numbers;
numbers = new int[SIZE];
int numOfElements = 0;
int i = 0;
cout << "Insert some numbers (! to end): ";
while((numbers[i] != '!') && (i < SIZE)){
cin >> numbers[i];
numOfElements++;
i++;
}
for(int i = 0; i < numOfElements; i++){
cout << numbers[i] << " ";
}
delete [] numbers;
return 0;
}
You increase numOfElements no matter what the user types. Simply do this instead:
if(isdigit(numbers[i]))
{
numOfElements++;
}
This will count digits, not characters. It may of course still be too crude if you want the user to input numbers with multiple digits.
Get numOfElements entered from user beforehand. For example
int main() {
int n;
cin >> n;
int * a = new int[n];
for (int i = 0; i < n; ++i)
cin >> a[i];
for (int i = 0; i < n; ++i)
cout << a[i] << endl;
delete[] a;
}
Input
4
10 20 30 40
Output
10 20 30 40
Since you declared array size, all indices will be zeros.
User input changes only the first x indices from zero to the value entered (left to right).
All other indices remains 0.
If you want to output only integers different from 0 (user input) you can do something like that:
for(auto x : numbers){
if(x!=0)cout<<x<<" ";
}
You can use vector and push_back the values from user input to get exactly the
size you need without zeros, then you can use this simple code:
for(auto x : vectorName)cout<<x<<" ";
Previous solutions using a counter is fine.
otherwise you can (in a while... or similar)
read values in a "temp" var
add if temp non zero
exit loop if counter >= SIZE-1 (you reach max slots)
increment counter
when You will print, form 0 to counter, you will get only non zero values.