My code is to extract odd number and even number in an 1D array.
#include <iostream>
using namespace std;
int main() {
int a[6] = {1,6,3,8,5,10};
int odd[]={};
int even[]={};
for (int i=0; i < 6; i++) {
cin >> a[i];
}
for (int i=0; i < 6; i++) {
if (a[i] % 2 == 1) {
odd[i] = a[i];
cout << odd[i] << endl;
}
}
cout << " " << endl;
for (int i=0; i < 6; i++) {
if (a[i] % 2 == 0) {
even[i] = a[i];
cout << even[i] << endl;
}
}
return 0;
}
the output is:
1
3
5
2
1
6
It shows that it successfully extract odd numbers but the same method applied to the even number. It comes with an issue while the even number is 4.
Could anyone help me find the cause here? Thanks.
You've got an Undefined Behavior, so result may be any, even random, even formatted hard drive.
int odd[] = {} is the same as int odd[/*count of elements inside {}*/] = {/*nothing*/}, so it's int odd[0];
Result is not defined when you're accessing elements besides the end of array.
You probably have to think about correct odd/even arrays size, or use another auto-sizeable data structure.
First, although not causing a problem, you initialize an array with data and then overwrite it. The code
int a[6] = {1,6,3,8,5,10};
can be replaced with
int a[6];
Also, as stated in the comments,
int odd[]={};
isn't valid. You should either allocate a buffer as big as the main buffer (6 ints) or use a vector (although I personally prefer c-style arrays for small sizes, because they avoid heap allocations and extra complexity). With the full-size buffer technique, you need a value like -1 (assuming you intend to only input positive numbers) to store after the list of values in the arrays to tell your output code to stop reading, or store the sizes somewhere. This is to prevent reading values that haven't been set.
I don't understand your problem when 4 is in the input. Your code looks fine except for your arrays.
You can use std::vector< int > odd; and then call only odd.push_back(elem) whem elem is odd.
Related
Preface: Currently reteaching myself C++ so please excuse some of my ignorance.
The challenge I was given was to write a program to search through a static array with a function and return the indices of the number you were searching for. This only required 1 function and minimal effort so I decided to make it more "complicated" to practice more of the things I have learned thus far. I succeeded for the most part, but I'm having issues with my if statements within my for loop. I want them to check 2 separate spots within the array passed to it, but it is checking the same indices for both of them. I also cannot seem to get the indices as an output. I can get the correct number of memory locations, but not the correct values. My code is somewhat cluttered and I understand there are more efficient ways to do this. I would love to be shown these ways as well, but I would also like to understand where my error is and how to fix it. Also, I know 5 won't always be present within the array since I'm using a pseudo random number generator.
Thank you in advance.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
// This is supposed to walk throught the array both backwards and forwards checking for the value entered and
// incrementing the count so you know the size of the array you need to create in the next function.
int test(int A[], int size, int number) {
int count = 0;
for (int i = 0; i <= size; i++, size--)
{
if (A[i] == number)
count++;
// Does not walk backwards through the array. Why?
if (A[size] == number)
count++;
}
cout << "Count is: " << count << endl;
return (count);
}
// This is a linear search that creates a pointer array from the previous "count" variable in function test.
// It should store the indices of the value you are searching for in this newly created array.
int * search(int A[], int size, int number, int arr_size){
int *p = new int[arr_size];
int count =0;
for(int i = 0; i < size; i++){
if(A[i]==number) {
p[count] = i;
}
count++;
}
return p;
}
int main(){
// Initializing the array to zero just to be safe
int arr[99]={0},x;
srand(time(0));
// Populating the array with random numbers in between 1-100
for (int i = 0; i < 100; i++)
arr[i]= (rand()%100 + 1);
// Was using this to check if the variable was actually in the array.
// for(int x : arr)
// cout << x << " ";
// Selecting the number you wish to search for.
// cout << "Enter the number you wish to search for between 1 and 100: ";
// cin >> x;
// Just using 5 as a test case.
x = 5;
// This returns the number of instances it finds the number you're looking for
int count = test(arr, (sizeof(arr)/4), x);
// If your count returns 0 that means the number wasn't found so no need to continue.
if(count == 0){
cout << "Your number was not found " << endl;
return 0;
}
// This should return the address array created in the function "search"
int *index = search(arr, (sizeof(arr)/4), x, count);
// This should increment through the array which address you assigned to index.
for(int i=0; i < count; i++) {
// I can get the correct number of addresses based on count, just not the indices themselves.
cout << &index[i] << " " << endl;
}
return 0;
}
I deeply appreciate your help and patience as well as I want to thank you again for your help.
I was given the integers 15, 16, 17 ,18 ,19 and 20.
I am supposed to put only the numbers divisible by 4 into a vector and then display the values in the vector.
I know how to do the problem using arrays but I'm guessing I don't know how to properly use pushback or vectors.
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> arrmain; int i,j;
for (int i = 15; i <=20 ; i++)
{
//checking which numbers are divisible by 4
if (i%4 == 0)
{ //if number is divisible by 4 inserting them into arrmain
arrmain.push_back(i);
//output the elements in the vector
for(j=0; j<=arrmain.size(); j++)
{
cout <<arrmain[i]<< " "<<endl;
}
}
}
return 0;
}
wanted output: Numbers divisible by 4: 16, 20
As already mentioned in the comments, you have a couple of problems in your code.
All which will bite you in the end when writing more code.
A lot of them can be told to you by compiler-tools. For example by using -Weverything in clang.
To pick out the most important ones:
source.cpp:8:10: warning: declaration shadows a local variable [-Wshadow]
for (int i = 15; i <=20 ; i++)
and
source.cpp:6:26: warning: unused variable 'i' [-Wunused-variable]
vector arrmain; int i,j;
Beside those, you have a logical issue in your code:
for values to check
if value is ok
print all known correct values
This will result in: 16, 16, 20 when ran.
Instead, you want to change the scope of the printing so it doesn't print on every match.
Finally, the bug you are seeing:
for(j=0; j<=arrmain.size(); j++)
{
cout <<arrmain[i]<< " "<<endl;
}
This bug is the result of poor naming, let me rename so you see the problem:
for(innercounter=0; innercounter<=arrmain.size(); innercounter++)
{
cout <<arrmain[outercounter]<< " "<<endl;
}
Now, it should be clear that you are using the wrong variable to index the vector. This will be indexes 16 and 20, in a vector with max size of 2. As these indexes are out-of-bounds for the vector, you have undefined behavior. When using the right index, the <= also causes you to go 1 index out of the bounds of the vector use < instead.
Besides using better names for your variables, I would recommend using the range based for. This is available since C++11.
for (int value : arrmain)
{
cout << value << " "<<endl;
}
The main issues in your code are that you are (1) using the wrong variable to index your vector when printing its values, i.e. you use cout <<arrmain[i] instead of cout <<arrmain[j]; and (2) that you exceed array bounds when iterating up to j <= arrmain.size() (instead of j < arrmain.size(). Note that arrmain[arrmain.size()] exceeds the vector's bounds by one because vector indices are 0-based; an vector of size 5, for example, has valid indices ranging from 0..4, and 5 is out of bounds.
A minor issue is that you print the array's contents again and again while filling it up. You probably want to print it once after the first loop, not again and again within it.
int main()
{
vector<int> arrmain;
for (int i = 15; i <=20 ; i++)
{
//checking which numbers are divisible by 4
if (i%4 == 0)
{ //if number is divisible by 4 inserting them into arrmain
arrmain.push_back(i);
}
}
//output the elements in the vector
for(int j=0; j<arrmain.size(); j++)
{
cout <<arrmain[j]<< " "<<endl;
}
return 0;
}
Concerning the range-based for loop mentioned in the comment, note that you can iterate over the elements of a vector using the following abbreviate syntax:
// could also be written as range-based for loop:
for(auto val : arrmain) {
cout << val << " "<<endl;
}
This syntax is called a range-based for loop and is described, for example, here at cppreference.com.
After running your code, I found two bugs which are fixed in code below.
vector<int> arrmain; int i, j;
for (int i = 15; i <= 20; i++)
{
//checking which numbers are divisible by 4
if (i % 4 == 0)
{ //if number is divisible by 4 inserting them into arrmain
arrmain.push_back(i);
//output the elements in the vector
for (j = 0; j < arrmain.size(); j++) // should be < instead of <=
{
cout << arrmain[j] << " " << endl; // j instead of i
}
}
}
This code will output: 16 16 20, as you are printing elements of vector after each insert operation. You can take second loop outside to avoid doing repeated operations.
Basically, vectors are used in case of handling dynamic size change. So you can use push_back() if you want to increase the size of the vector dynamically or you can use []operator if size is already predefined.
I am having trouble understanding why this exception is being thrown. I allocated an array to receive 100 int values and want to store all odd numbers under 200 into the array (which should be 100 integer values). I'm trying to understand why my code is not working.
I have called my function to allocate an array of 100 int values. After, I created a for-loop to iterate through and store integers into the array however I created an if statement to only store odd numbers. What I can't understand is if I put my counter to 200 and use the if statement an exception is thrown, but if I don't insert the if statement and only put my counter to 100 all numbers between 1-100 stored and an exception won't be thrown.
The only thing I can think of that's causing this is when my counter is at 200 and I have the if statement to catch all odd number, somehow all numbers under 200 are being stored in the array causing the exception to be thrown.
int *allocIntArray(int);
int main() {
int *a;
a = allocIntArray(100);
for (int count = 1; count < 200; count++) {
if (a[count] % 2 == 1) {
a[count] = count;
cout << a[count] << endl;
}
}
delete[] a;
return 0;
}
int *allocIntArray(int size) {
int *newarray = new int[size]();
return newarray;
}
When I look at the program output, it only displays the odd numbers yet the exception is being thrown. That tells me my if statement is working yet something is being muddied up.
What am I missing?
Thanks for your time and knowledge.
Cause of the error
If you have an array a that was created with n elements, it is undefined behavior when trying to access an array element out of bouds. So the index MUST always be between 0 and n-1.
So the behavior of your program is undefined as soon as count is 100, since evaluating the condition in the if-clause already tries to access out of bounds.
Adjustment that does what you want
Now in addition, there is a serious bug in your program logic: If you want to add numbers that satisfy some kind of condition, you need 2 counters: one for iterating on the numbers, and one for the last index used in the array:
for (int nextitem=0, count = 1; count < 200; count++) {
if (count % 2 == 1) { // not a[count], you need to test number itself
a[nextitem++] = count;
cout << count << endl;
if (nextitem == 100) { // attention: hard numbers should be avoided
cout << "Array full: " << nextitem << " items reached at " << count <<endl;
break; // exit the for loop
}
}
}
But, this solution requires you to keep track of the last item in the array, and the size of the array (it's hard-coded here).
Vectors
You are probably learning. But in C++ a better solution would be to use vector instead of an array, and use push_back(). Vectors manage the memory, so that you can focus on your algorithm. The full program would then look like:
vector<int> a;
for (int count = 1; count < 200; count++) {
if (count % 2 == 1) {
a.push_back(count);
cout << count << endl;
}
}
cout << "Added " << a.size() << " elements" <<endl;
cout << "10th element: "<< a[9] << endl;
The problem is not how many numbers you're storing but where you're storing them; you're storing 101 in a[101], which is obviously wrong.
If the i:th odd number is C, the correct index is i-1, not C.
The most readable change is probably to introduce a new counter variable.
int main() {
int a[100] = {0};
int count = 0;
for (int number = 1; number < 200; number++) {
if (number % 2 == 1) {
a[count] = number;
count += 1;
}
}
}
I think transforming this from a search problem to a generation problem makes it easier to get right.
If you happen to remember that every odd number C can be written on the form 2 * A + 1for some A, you' will see that the sequence you're looking for is
2*0+1, 2*1+1, 2*2+1, ..., 2*99+1
so
int main()
{
int numbers[100] = {0};
for (int i = 0; i < 100; i++)
{
numbers[i] = 2 * i + 1;
}
}
You can also go the other way around, looping over the odd numbers and storing them in the right place:
int main()
{
int numbers[100] = {0};
for (int i = 1; i < 200; i += 2) // This loops over the odd numbers.
{
numbers[i/2] = i; // Integer division makes this work.
}
}
I can't understand why the outputs are different when I put 1 array into a very simple for loop and when I put two arrays into it.
int arrR[100];
int arrN[100];
//function to run the simulation
void runsim(){
for(int i=1;i<=100;i++){
arrN[i] = i;
arrR[i] = i;
}
}
//function to print the array
void printarr(int x[100]){
for(int i=0;i <= 100;i++){
cout << x[i] << ", ";
}
cout << endl;
}
int main(){
runsim();
printarr(arrR);
printarr(arrN);
return 0;
}
This outputs arrR as: 0,1,2,3,4,5,6,...,100 which is what I want, but
it outputs arrN as: 100,1,2,3,4,5,6,...,100 which I do not understand.
If I remove arrR from the for loop arrN prints how I want
int arrR[100];
int arrN[100];
//function to run the simulation
void runsim(){
for(int i=1;i<=100;i++){
arrN[i] = i;
}
}
//function to print the array
void printarr(int x[100]){
for(int i=0;i <= 100;i++){
cout << x[i] << ", ";
}
cout << endl;
}
int main(){
runsim();
printarr(arrN);
return 0;
}
This outputs arrN as 0,1,2,3,4,5,6,...,100
Interestingly, if I change all the 100's to 10's in the code this problem also goes away even if I keep both arrays in the for loop.
Can anyone help me understand what I'm missing? I'm sure it's simple because I'm pretty new to C++. Thank you!
Note the condition of for is i<=100, equals sign means you will access the array by arrN[100], then get out of the bound. This is undefined behavior, anything is possible. The valid range should be [0, N) (N = 100), i.e. arrN[0], …, arrN[N - 1] (i.e. arrN[99]).
You might want to change all the conditions to i < 100.
Please note that array indexing start from 0 instead of 1 ends at n-1 instead of n. Now in your function runsim() you are accessing the assigning value 100 to arrN[100] and arrR[100] which is not possible leads to undefined behavior.
You should change the for loop condition
for(int i = 0; i < 100; i++) {
// Do something.
}
Please note that accessing element out bound will not produce any error as well. For more detail please refer Accessing an array out of bounds gives no error
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
My assignment is to have the user type in how many elements are in an array then enter integer number to be put in the array. I then have to sort through the array and find the largest number and print out the elements of the array but if there is a repeat then only print that number one time. I also have to print out the number of times each element in the array occurs. For example if the user types in that there is 5 elements then enters 2, 1, 2, -3, 2 then it should print -3 with 1 count, 1 with 1 count, and 2 with 3 count. So far I have it so it will print out the elements and delete the repeats but I cant get it to print out the correct number of occurrences for each element. This is my code so far.
void findRepeats(int numbers[], int num)
{
int instances = 0;
cout << "Number" << " " << "Occurrences" << endl;
for (int i = 0; i < num; i++)
{
bool matching = false;
instances = 1;
for (int j = 0; (j < i); j++)
{
if (numbers[i] == numbers[j])
{
instances++;
matching = true;
}
}
if (!matching)
cout << numbers[i] << " " << instances << endl;
}
}
Right now its saying all number occur only 1 time
One approach that you could take, is to sort the numbers first, before deciding how many duplicates there are. That way, it will be easier to avoid printing results for the same number more than once, and you also won't have to loop through the entire array for each number.
void findRepeats(int numbers[], int num);
int main(){
int array[] = {2, 1, 2, -3, 2};
findRepeats(array,5);
}
void findRepeats(int numbers[], int num) {
//sort the array first
std::sort(numbers, numbers + num);
int last = numbers[0];
int count = 0;
cout << "Number of Occurrences\n";
for (int i = 0; i < num; i++) {
if (last == numbers[i]) {
++count;
} else {
cout << last << " " << count << '\n';
count = 1;
}
last = numbers[i];
}
if (count > 0) {
cout << last << " " << count << '\n';
}
}
prints:
Number of Occurrences
-3 1
1 1
2 3
I would use map or unordered_map to, well..., map the integer to the number of it's occurrences. It makes things quite simple, as it basically takes care of the duplicates for you.
#include <iostream>
#include <unordered_map>
using namespace std;
void reportCounts(const int numbers[], const size_t size){
unordered_map<int, unsigned int> counts;
//unfortunately range-for here would a little PIA to apply
//or at least I don't know convenient way
for(size_t i = 0; i < size; ++i) {
counts [ numbers[i] ]++; //increase `count` of i-th number
}
//print results
for(auto count : counts ){
cout << count.first << ' ' << count.second << endl;
}
}
int main(){
int array[] = {2, 1, 2, -3, 2};
reportCounts(array,5);
}
Since it's an assignment I am leaving figuring out the c++ shenaningans to you and http://cppreference.com. Keywords are map, map::iterator and maybe associative container which map in an example of.
I do understand that it might be harder to understand than plain implementation of some algorithm, but this is probably close to optimal solution in modern c++, and putting effort into understanding how and why it works should prove beneficial. One should notice how much less of code had to be written, and no algorithm had to be invented. Less implementation time, less place to make mistakes, less testing.
Search your array. For every integer, either record it, or increment your count of it. Repeat process till done, then print it.
How? you say? One approach would be to use parallel arrays to store the unique integers found, and another to store the count of integers. Then print the unique integers and their counts.
Code example of simple search algorithm:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void print(vector<int> valueArray,vector<int> countArray){
for(unsigned int i = 0; i < valueArray.size(); ++i){
cout<<"Found value "<<valueArray[i]<<": "<<countArray[i]<<" times."<<endl;
}
}
void findRepeats(vector<int> testArray,vector<int> &valueArray,vector<int> &countArray){
for(unsigned int i = 0; i < testArray.size(); ++i){
if(valueArray.size() == 0){
valueArray.push_back(testArray[i]);
countArray.push_back(1);
}else{
bool newEntry = true;
for(unsigned int j = 0; j < valueArray.size(); ++j){
if(testArray[i] == valueArray [j]){
countArray[j]++;
newEntry = false;
break;//After find, break out of j-for-loop to save time.
}
}
if(newEntry){
valueArray.push_back(testArray[i]);
countArray.push_back(1);
}
}
}
}
int main(){
vector<int> testArray; //To store all integers entered.
vector<int> valueArray; //To store non-copied integers, dynamically, else handle it yourself.
vector<int> countArray; //To count increments of numbers found, dynamically, else handle it yourself.
testArray = {0,2,5,4,1,3,6,2,5,9,8,7,4,1,2,6,5,4,8,3,2,1,5,8,6,9,8,7,4,4,5,6,8,2,1,3,0,0,1,2,0,2,5,8};//Dummy data.
findRepeats(testArray,valueArray,countArray);//Function to find statistics on testArray.
cout<<"\nPrinting found characters, and number of times found: "<<endl;
print(valueArray,countArray);
return 0;
}
Output would be something like:
Printing found characters, and number of times found:
Found value 0: 4 times.
Found value 2: 7 times.
Found value 5: 6 times.
Found value 4: 5 times.
Found value 1: 5 times.
Found value 3: 3 times.
Found value 6: 4 times.
Found value 9: 2 times.
Found value 8: 6 times.
Found value 7: 2 times.
In the above, I used vectors for simplicity, but if you must do so with c-style arrays, one approach would be to create all three vectors the same size, and keep one integer counter for number of indices used in the valueArray and countArray; they should share, since they're related 1 to 1. And you will need to pass it to the findRepeats function as well.
Having arrays of the same size will ensure that your values and counts will fit in your array; this would happen if every number entered was unique.