writing values to an array from another array excluding unwanted values c++ - c++

For context, I can't use anything that isn't taught in csc101 (what you learned may have been different) so I can't use things like vectors, structs, and classes. More context, I have an assignment which requests I have a function which takes an array numarray with random values, and removes the values from 20 to 40. As I understand it, the best way to do that is to make a new array and take the valid values from numarray and put them in a new array temparray. I tried implementing this the best way I could figure up, but it seems to only spit out a set number which is a long negative number over and over in a loop. I know it is this function because when not called I don't have a problem. The problem also doesn't occur if I comment out the while loop at the end of the function. I will first attach the function in question, and then the whole of the program for added context. Open to any criticism, but passing the class is my priority over elegance, and efficiency. If the professor wants something done a certain way, I must oblige. Thanks for your time.
The required function:
void Delete(int* numarray, int *temparray) {
int arrayindex = 0;
for (int index = 0; index < 100; index++) {
if (numarray[index] < 20 && numarray[index] > 40) {
temparray[arrayindex] = numarray[index];
} arrayindex++;
}
cout << arrayindex << endl;
cout << temparray[arrayindex] << endl;
while (arrayindex <! 0) {
cout << temparray[arrayindex - 1] << endl;
}
}
The whole project:
#include <iostream>
#include <fstream>
#include <time.h>
#include <stdlib.h>
#include <cstddef>
#include <array>
using namespace std;
ofstream randomData;
ifstream inputrandomData;
void randomgenerator();
void read(int *numarray);
void printArray(int *numarray);
void searchArray(int* numarray);
void Delete(int* numarray, int* temparray);
void randomgenerator() {
srand(time(0));
randomData.open("randomData.txt");
for (int counter = 0; counter < 100; counter++) {
randomData << rand() % 100+1 << endl;
}
randomData.close();
}
void read(int *numarray) {
inputrandomData.open("randomData.txt");
for (int i = 0; i < 100; i++) {
inputrandomData >> numarray[i];
}
inputrandomData.close();
}
void printArray(int *numarray) {
for (int index = 0; index < 100; index++) {
cout << numarray[index] << endl;
}
}
void searchArray(int* numarray) {
int searchedArray[6] = {};
for (int index=0; index < 100; index++) {
if (numarray[index] > searchedArray[0]) {
searchedArray[0] = numarray[index];
searchedArray[1] = index;
}
}
for (int index = 0; index < 100; index++) {
if (numarray[index] > searchedArray[2] && numarray[index] < searchedArray[0]) {
searchedArray[2] = numarray[index];
searchedArray[3] = index;
}
}
for (int index = 0; index < 100; index++) {
if (numarray[index] > searchedArray[4] && numarray[index] < searchedArray[2]) {
searchedArray[4] = numarray[index];
searchedArray[5] = index;
}
}
cout << "Largest Number: " << searchedArray[0] << " " << "Index: " << searchedArray[1] << endl;
cout << "Second Largest Number: " << searchedArray[2] << " " << "Index: " << searchedArray[3] << endl;
cout << "Third Largest Number: " << searchedArray[4] << " " << "Index: " << searchedArray[5] << endl;
}
void Delete(int* numarray, int *temparray) {
int arrayindex = 0;
for (int index = 0; index < 100; index++) {
if (numarray[index] < 20 && numarray[index] > 40) {
temparray[arrayindex] = numarray[index];
} arrayindex++;
}
cout << arrayindex << endl;
cout << temparray[arrayindex] << endl;
while (arrayindex <! 0) {
cout << temparray[arrayindex - 1] << endl;
}
}
int main() {
int numarray[100] = {};
int temparray[100] = {};
randomgenerator();
read(numarray);
printArray(numarray);
searchArray(numarray);
Delete(numarray, temparray);
return 0;
}

Here was the solution I was prompted to come up with. There were a couple logical flaws.
First, my conditional would never be true as I used the && operator which means the number would have to be lower than 20 AND greater than 40. Changed that to || operator to check for one or the other. Then, as stated in the comments, I had been overthinking it by creating another array. You have to have two different index counters in order to read from the original data set, and to write the new data set in behind it. Now, when ran, the numarray takes values at the numarray[arrayindex] which is only incremented when the conditional is called, and reads from numarray[index] which increments on every for loop. Here is the edited function below:
void Delete(int* numarray) {
int arrayindex = 0;
for (int index = 0; index < 100; index++) {
if (numarray[index] < 20 || numarray[index] > 40) {
numarray[arrayindex] = numarray[index];
arrayindex++;
}
}
cout << arrayindex << endl;
for (int newindex = 0; newindex < arrayindex; newindex++) {
cout << numarray[newindex] << endl;
}
}
I removed temparray from the program entirely. Thanks for the help.

You can break up the problem into many pieces at first so that it is easier to program and understand. If you're struggling, keep splitting up the task into smaller simpler functions, like this:
// remove a range of values from arr
void remove_range(int *arr, int size, int from, int to) {
for (int r = from; r <= to; r++) {
remove_all(arr, size, r);
}
}
// remove all of a single value from arr
void remove_all(int *arr, int size, int value) {
for (int i = 0; i < size; i++) {
if (arr[i] == value) {
remove_one(arr, size, value);
}
}
}
// remove the first occurrence of a value from arr
void remove_one(int *arr, int size, int value) {
for (int i = 0; i < size; i++) {
if (arr[i] == value) {
remove_i(arr, size, value);
}
}
}
// remove the value at an index of arr by shifting all the entries after it left one
// and putting a 0 at the end in case this is the first removal
void remove_i(int *arr, int size, int i) {
for (; i < size - 1; i++) {
arr[i] = arr[i + 1];
}
arr[i] = 0;
}

If I'm understanding your project correctly, you have the following main objectives:
Without using std::vector or other classes/structs, copy an array into another
The copied-to array must not contain values from 20-40 (assuming inclusive)
With that in mind, there are some other things you may want to keep in mind. For example, does speed or memory matter more?
If speed matters more, you can create an array (named copy_to) with equal size of copy_from array. Then, just test every value in copy_from to make sure it's not within [20, 40] before copying it to copy_to. However, If memory management matters more, not only would I do everything from the "speed" method, but I would also keep track of how many elements are being added to copy_to. After they are copied, make a new array (copy_to_final) of the exact size needed, copy copy_to to copy_to_final, and delete copy_to.
Here's what the code would look like for the speed method:
int* make_prejudice_array(int[] copy_from, size_t size)
{
// Make array to store new values in
int* copy_to = new int[size];
size_t copy_to_size = 0;
// Copy valid values into 'copy_to'
for (size_t i = 0; i < size; ++i)
{
if (copy_from[i] < 20 || copy_from[i] > 40)
{
copy_to[copy_to_size] = copy_from[i];
copy_to_size++;
}
}
return copy_to;
}
And, for the memory management way, just a small addition:
int* make_prejudice_array(int[] copy_from, size_t size)
{
int* copy_to = new int[size];
size_t copy_to_size = 0;
for (size_t i = 0; i < size; ++i)
{
if (copy_from[i] < 20 || copy_from[i] > 40)
{
copy_to[copy_to_size] = copy_from[i];
copy_to_size++;
}
}
// Make new array to hold the exact number of elements needed
int* copy_to_final = new int[copy_to_size];
for (size_t i = 0; i < copy_to_size; ++i)
copy_to_final[i] = copy_to[i];
// Don't forget to delete 'copy_to' to prevent a mem leak
delete[] copy_to;
copy_to = nullptr;
return copy_to_final;
}
If I missed something from your question. Let me know and I'll do my best to incorporate it. Hope that helps!

Related

Why is my loop not returning the right answer?

I can't figure it out. What is wrong with my code? I am new to programming.
Program required output: Write a C++ program to find the maximum-occurring character in an array, using a loop.
My code:
#include <string.h>
using namespace std;
void FindMaxChar(char Word[])
{
int count = 0;
int max = 0;
char index = 0;
int length = strlen(Word);
for (int i = 0; i < length; i++)
{
index = Word[i];
for (int j = 0; j < length; j++)
{
if (index == Word[j])
{
count++;
}
}
if (count > max)
{
max = count;
index = Word[i];
}
}
cout << index << " is repeating " << max << " times.";
}
int main()
{
char Word[100] = {0};
cout << "Enter the Word = ";
cin.get(Word,100);
FindMaxChar(Word);
}
My Output:
Enter the Word = caaar
r is repeating 11 times.
You never reset count each loop. So you continue incrementing it but never clear it.
Add count = 0 to the beginning of the outer for loop:
for (int i = 0; i < length; i++)
{
count = 0; // Reset counter
You're also trying to use index for two different purposes. You're both using it to store the current character you're looking at (not an index, kind of confusing that you named it like that), AND the character you've seen the most (still not an index, also confusing).
Instead, you need another variable here.
Also note that if you declare Word as char Word[100], it can only hold a c-string of length 99 (to leave room for the null character). So your cin should actually be:
cin.get(Word, 99);
Thanks to the great people of this community.
I am able to find my error and corrected it.
Correct Code :
#include <iostream>
#include <string.h>
using namespace std;
void FindMaxChar(char Word[])
{
int count = 0;
int max = 0;
char index = 0;
char final = 0;
int length = strlen(Word);
for (int i = 0; i < length; i++)
{
index = Word[i];
count = 0;
for (int j = 0; j < length; j++)
{
if (index == Word[j])
{
count++;
}
}
if (count > max)
{
max = count;
final = index;
}
}
cout << final << " is repeating " << max << " times.";
}
int main()
{
char Word[100] = {0};
cout << "Enter the Word = ";
cin.get(Word,99);
FindMaxChar(Word);
}

Program is meant to count how many duplicates are in an array. However, it returns the wrong frequency values

Normally I would use other methods to fix this program but I am not allowed to use advanced techniques for this project, and so what I have is more or less as far as I'm allowed to go.
So my program is meant to take in an array with 10 numbers and then output how many of each value is in the array. For example, {1, 1, 1, 1, 1, 2, 2, 2, 2, 2} is meant to return
5 1
5 2
However, it returns
6 1
4 2
I've made sure that the finalData and Data arrays are holding the proper values.
cout << count(data, data + MAX_VALUE, finalData[i+1]) << " " << data[i] << "\n";
seems to be outputting the wrong value.
for some reason. I believe the error is in my last function, getResults, more specifically the last for loop. Here is that function.
void getResults(int finalData[], int data[])
{
int temp[MAX_VALUE];
int j = 0;
for (int i = 0; i < MAX_VALUE - 1; i++)
if (finalData[i] != finalData[i + 1])
temp[j++] = finalData[i];
temp[j++] = finalData[MAX_VALUE - 1];
for (int i = 0; i < j; i++)
{
finalData[i] = temp[i];
}
for (int i = 0; i < j; i++)
{
cout << count(data, data + MAX_VALUE, finalData[i+1]) << " " << data[i] << "\n";
}
}
This is my complete code.
#include<iostream>
#include<iomanip>
#include<string>
#include<cmath>
#include <algorithm>
using namespace std;
void printHeader();
int getData(string);
void getResults(int finalData[], int data[]);
const int MAX_VALUE = 10;
int main(void)
{
int countValue = 0;
int freq = 0;
printHeader();
int data[MAX_VALUE] = {};
int frequency[MAX_VALUE] = {};
for (int i = 0; i < MAX_VALUE; i++)
{
cout << "Please enter data position " << i + 1 << "\n";
data[i] = getData("\nPlease enter a valid integer.\n");
}
sort(data, data + MAX_VALUE);
int values[MAX_VALUE] = {};
int secondData[MAX_VALUE] = {};
for (int i = 0; i < MAX_VALUE; i++)
{
secondData[i] = data[i];
}
getResults(data, secondData);
return 0;
}
void printHeader()
{
}
int getData(string error)
{
int userInput = 0;
do
{
cin >> userInput;
if (cin.fail())
{
cout << error;
}
} while (cin.fail());
return userInput;
}
void getResults(int finalData[], int data[])
{
int temp[MAX_VALUE];
int j = 0;
for (int i = 0; i < MAX_VALUE - 1; i++)
if (finalData[i] != finalData[i + 1])
temp[j++] = finalData[i];
temp[j++] = finalData[MAX_VALUE - 1];
for (int i = 0; i < j; i++)
{
finalData[i] = temp[i];
}
for (int i = 0; i < j; i++)
{
cout << count(data, data + MAX_VALUE, finalData[i+1]) << " " << data[i] << "\n";
}
}
Got the right answer. Made the changes I listed at the top as well as the following change to the count function.
cout << count(data, data + MAX_VALUE, finalData[i]) << " " << finalData[i] << "\n";
You have done a simple error. When you call getResults you pass the same array(pointer) to 2 different parameters. Now when you update finalData the unwanted side effect update also data(they are the same pointer(with different name). So when you call count will not return the expected result.
To solve this problem you can do a copy of the input array and give it as second parameter of getResults(...) function.

Finding the mode of a sorted array using bin search

Hi there i've been tasked with Writing a simple program that is given an array of integers and determines the mode, which is the number that appears most frequently in the array.
The approach i'm trying to adopt is using a bubble sort with a bin search algorithm my level of knowledge is at a beginner stage can someone help point me?
Where i'm going wrong i believe it to be passing the correct search value to find it in the array! But i maybe wrong but some help would be very much appreciated, thanks in advance for those to take time to try help me.
#include <iostream>
using namespace std;
const int arrayLength = 10;
int searchVal;
int numGroup[arrayLength];
bool isSorted(int [], int arrayLength);
int binSearch(int [],int arrayLegth,int searchVal);
int main()
{
// Take in num
for (int index = 0; index < arrayLength; index++)
{
cout << "Enter Number: ";
cin >> numGroup[index];
}
// Sort numbers
//var to hold the val being swaped
int swapHolder = 0;
//bubble sort
for (int iSort = 0; iSort < arrayLength; iSort++)
{
for (int jSort = (iSort + 1); jSort <= arrayLength - 1; jSort++)
{
if (numGroup[iSort] > numGroup[jSort])
{
swapHolder = numGroup[iSort];
numGroup[iSort] = numGroup[jSort];
numGroup[jSort] = swapHolder;
}
}
}
//passes the sorted array and the length to the isSorted
isSorted(numGroup, arrayLength);
return 0;
}
bool isSorted(int numGroup[], int arrayLength){
cout << "Final result" << endl;
for (int index = 0; index < arrayLength - 1 ; index++)
{
if (numGroup[index] > numGroup[index + 1])
{
cout << "it's false";
system("pause");
return false;
}
cout << numGroup[index] << endl;
//cout << arrayLength << endl;
}
cout << numGroup[arrayLength - 1] << endl;
//trying to make searchVal
for (int i = 0; i < numGroup[arrayLength - 1]; i++)
{
if (numGroup[i] == numGroup[i])
{
int searchVal = numGroup[i];
}
}
binSearch(numGroup, arrayLength, searchVal);
cout << "It's true ";
system("pause");
return true;
}
int binSearch(int numGroup[], int arrayLength,int searchVal){
int low = 0;
int high = arrayLength - 1;
int mid;
while (low <= high)
{
mid = (low + high) / 2;
//search through the array
if (searchVal == numGroup[mid])
{
return mid;
}
else if (searchVal > numGroup[mid])
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
cout << "In bin search " << mid;
return mid;
}
You don't need to sort the array. You can have another array (freq) which will count the numbers appearances. So, a mini code for that:
int myArray[10];
int freq[1000]; //we assume that the numbers are smaller than 1000
void count()
{
for(int i = 0; i < 10; ++i)
{
++freq[v[i]];
}
}
int ReturnModeElement()
{
int maxFreq = -1;
int element = -1;
for(int i = 0 ; i < 10; ++i)
{
if(freq[v[i]] > maxFreq)
{
maxFreq = freq[v[i]];
element = v[i];
}
}
return element;
}
I hope you got the idea :)

c++ dynamic array Floating Point exception

For my homework I had to design an arraylist in c++ using only 1d arrays and pointers to make the array dynamic. I have done ample testing and my functions work correctly, but when I use the main that the teacher has provided me I get this floating point error. The point of this homework is to create a class that will work for the teachers main without changing any code in the main
here is the main:
#include "ArrayList.h"
#include <iostream>
using namespace std;
int main(int argc,char *argv[])
{
ArrayList arr;
for (int i=1;i<=50;i++)
{
arr.push_back(i);
}
cout << "Should contain numbers 1..50, is ";
cout << arr.toString() << endl;
for (int i=arr.size()-1;i>=1;i--)
{
arr.erase(arr[i]);
}
cout << "Should contain only 1, is ";
cout << arr.toString() << endl;
arr.erase(arr[0]);
for (int i=1;i<=50;i++)
{
if (i<=2)
arr.push_back(i);
else
{
int j=1;
while ((j<arr.size()) && (i%arr[j]!=0))
j++;
if (j==arr.size())
{
arr.push_back(i);
}
}
}
cout << "Prime numbers between 1 and 50 are: " << arr.toString() << endl;
}
here is my cpp:
#include<iostream>
#include<string>
#include<sstream>
#include "ArrayList.h"
using namespace std;
void ArrayList:: intialArr(int arr[])
{
for(int i = 0; i < length; i++)
{
arr[i] = 0;
}
}
string ArrayList:: toString()
{
std::ostringstream ss;
for(int i = 0; i < capacity; i++)
{
if(arr[i]>0 || arr[i] <0)
{
ss << arr[i] << " ";
}
}
return ss.str();
}
ArrayList::ArrayList()
{
length = 1;
capacity=0;
arr = new int[length];
intialArr(arr);
}
int& ArrayList:: operator[] (unsigned int i)
{
return arr[i];
}
void ArrayList:: push_back(int m)
{
if(capacity>=length)
{
int oldlength = length;
length = length*2;
int* curArr = new int[length];
intialArr(curArr);
for (int i = 0; i < oldlength; i++)
{
curArr[i] = arr[i];
}
delete [] arr;
arr = curArr;
}
arr[capacity] = m;
capacity++;
}
void ArrayList:: erase(int m)
{
if(capacity == length/2)
{
length = length/2;
int* curArr = new int[length];
intialArr(curArr);
for (int i = 0; i<capacity; i++)
{
curArr[i] = arr[i];
}
delete [] arr;
arr = curArr;
}
for(int i = 0; i < capacity; i++)
{
if(arr[i]==m)
{
for(int j = i; j<length; j++)
{
arr[j] = arr[j+1];
}
capacity--;
break;
}
}
cout << "length = " << length << " capacity = " << capacity << " capacity/length = " << capacity*2 << endl;
}
from what I have read online floating point exceptions are normally thrown when you try to divide by zero or an infinate value arises but I dont understand how I am getting either of these issues to arise.
My code get through the main where number 1-50 are added and deleted but I get the error once I go into setting up the array to hold prime numbers (after the arr.erase(arr[0]) in the main)
I just set a couple of tags in the main to find what my number look like going into the while ((j<arr.size()) && (i%arr[j]!=0))and i find that my numbers before the crash are
j = 1 and arr[j] = 2
i = 5 and arr.size() = 4

Treating an array of bools as though incrementing in binary [duplicate]

This question already has answers here:
Bitset in C++, about continuously add
(2 answers)
Closed 8 years ago.
I'm trying to create a loop that changes the values in a boolean array so that it looks like the array is incrementing in binary values.
For example
1st iteration [0|0|0]
2nd iteration [0|0|1]
3rd iteration [0|1|0]
4th iteration [0|1|1]
etc.
This array is dynamic, however, and can be different sizes. So whatever loop I write would need to also work on an array with five elements instead of three.
Apologies for not having any starting code, but I've been frustrating myself with this for hours and still can't even come up with how to begin.
Try this. This may not be complete but you could do something similar
#include <iostream>
using namespace std;
void increment(bool* array, int len)
{
for (int i = len - 1; i >= 0; --i)
{
if ( ! array[i])
{
array[i] = true;
return;
}
array[i] = false;
}
}
int main()
{
bool* array = new bool[10];
for (int i = 0; i < 5; ++i)
{
increment(array, 10);
for (int i = 0; i < 10; ++i)
{
cout << (array[i] ? 1 : 0) << "|";
}
cout << endl;
}
return 0;
}
#include <iostream>
#include <cmath>
#include <memory>
using namespace std;
void ArrayIterate(int);
void printArray(bool*,int);
void ArrayIterate(int arraySize)
{
int decimal_value = 0;
int decimal_place_value = 0;
bool* boolArray = new bool(arraySize);
long double max_itr = pow(2,arraySize);
for (int i = 0; i < max_itr ; ++i)
{
decimal_value = i;
// set array values
for ( int k = arraySize - 1; k >= 0; --k)
{
decimal_place_value = pow(2,k);
if( decimal_value != 0 && decimal_value / decimal_place_value >= 1 )
{
boolArray[k] = true;
decimal_value -= decimal_place_value;
}
else
boolArray[k] = false;
}
printArray(boolArray,arraySize);
cout << " = " << i << endl; ;
}
delete boolArray;
return;
}
void printArray(bool* boolArray, int arraySize)
{
cout << "\t";
for(int i = arraySize - 1; i >= 0; --i)
cout << ((boolArray[i] == true)? 1 : 0) << " ";
return;
}
int main()
{
cout << "\n\n";
ArrayIterate(4);
cout << "\n\n" << endl;
return 0;
}