C++ Check the length of an array with Zeros and nulls - c++

I have an int array, of let say... 1000 elements. The user enters 128 and it fills the array as 821. Before it gets said, let me say, it has to be backwards for simplicity of other functions. To get the length I use
int count = 0;
for (int i = 0; array1[i] != '\0'; ++i)
{
count++;
}
this works great. Until they enter a number with a 0 in it, such as 0, or 100.
The array is filled as 001, but the test stops it immediately since 0 is equal to '\0'
I cant use sizeof(array1)/sizeof(*array1) because then when I go to print the array I get tons of zeros followed by the number. It does print correctly, but its not what I want.
Any solutions?

I think a better way is to fill the whole array with an invalid value (such as -1) before you use it. By saying "invalid" it can be anything except 0-9 according to your description.
memset(array1, -1, sizeof(array1));
// doing things
And why don't you just save the numbers as characters since they are from user input? Just use '0' instead of '\0' to represent the zero, so you don't have the issue. You even can use strlen to get the length directly if you guarantee that there is always '\0' in the end of array:
// array size is 1001 instead of 1000 to reserve a '\0' in the end
char array1[1001] = {'8', '2', '1'}
size_t count = strlen(array1);

What you need to do is convert the digits to corresponding characters.
Lets say, you have 1230. In your array you actually store 1 + '0', 2 + '0', 3 + '0' and '0'. '0' being the ASCII value of the key that has 0 printed on it.
That way you will never confuse '0' with \0.

you could dertermine the amount of digits your number has and then dynamically allocate the array with the calculated size.

There are two approaches I can think of:
You increase the size after each element the user inputs
You mark the end with a number the user will never input
For example on the first case:
char array1[1000];
int count = 0;
while(!the_end)
{
std::cin >> array1[count++]
}
// From now, every time you add elements to the array, increase the "size" variable
std::cout << "Size: " << count << std::endl;
For the second case, there are some methods, but what I think which would be the best for you, is by fulfilling the array with the invalid value before you start to get the input from the user:
char array1[1000] = {-1};
// Start getting the input...
int count = 0;
for(int i = 0; array1[i] != -1; ++i)
{
count++;
}
std::cout << "Size: " << count << std::endl;
Note: if you're stuck on this, then your code probably has some design flaws. For the design to be good, you'd be using the first approach I suggested and not trying to find the size afterwards. Or better, you could be using std::vector as suggested in the commentaries, or at least could have some type of "tracking" for the elements you input to the array.

Related

Last Element in my Array is a large number that I never inputted

I'm storing the results of a "Dice Roll" in an Array.
Everything seems to be working fine, except the last value of the Array is a ╠ (-858993460)?
I tried troubleshooting and its happening right in the beginning and I don't know why.
const int QDice = 3;
int Domain = 6 * QDice;
int CD[6 * QDice]{};
do
{
cout << "Array CD[" << i << "] = " << CD[i] << "\n";
i++;
} while (i <= Domain);
This yields:
Array CD[1] = 0
...
Array CD[18] = -858993460
Everything is fine accept the last element.
C++ array index starts from 0, so the array CD[] range is from 1 to 17. When the Domain becomes 18, the array is out of bounds. I suggest that you could modify the code to the following code.
do
{
cout << "Array CD[" << i << "] = " << CD[i] << "\n";
i++;
} while (i <= Domain - 1);
As mentioned in the comments and another answer, you're assuming 1-based indexing while c++ arrays use 0-based indexing. This means index 18 is out-of-bounds, i.e., it is past the end of the array. But why that does that negative number show up?
First of all, when an out-of-bounds condition exists, the program exhibits undefined behaviour. That means the program can do literally anything, whether it's what you intended or not. In practice, though, the program will often assume that arrays are large enough for the index being used. So in your case, it will look up the memory where index 18 ought to be (as if the array were large enough for that), and then try to interpret the bytes it finds there as some meaningful value.
Now, as a general rule, memory can have any value at all, unless you set it to something specific. By initializing your array, you set the memory for each array element to a definite value (0). But just past the end of the array is memory that you haven't set, so those bytes could be anything. In your case, they just happen to be set in such a way that they are interpreted as the -858993460, but that could just as well be any other value.

C++: First non-repeating character, O(n) time using hash map

I'm trying to write a function to get the first non-repeating character of a string. I haven't found a satisfactory answer on how to do this in O(n) time for all cases. My current solution is:
char getFirstNonRepeated(char * str) {
if (strlen(str) > 0) {
int visitedArray[256] = {}; // Where 256 is the size of the alphabet
for (int i = 0; i < strlen(str); i++) {
visitedArray[str[i]] += 1;
}
for (int j = 0; j < 256; j++) {
if (visitedArray[j] == 1) return j;
}
}
return '\0'; // Either strlen == 0 or all characters are repeated
}
However, as long as n < 256, this algorithm runs in O(n^2) time in the worst case. I've read that using a hash table instead of an array to store the number of times each character is visited could get the algorithm to run consistently in O(n) time, because insertions, deletions, and searches on hash tables run in O(1) time. I haven't found a question that explains how to do this properly. I don't have very much experience using hash maps in C++ so any help would be appreciated.
Why are you repeating those calls to strlen() in every loop? That is linear with the length of the string, so your first loop effectively becomes O(n^2) for no good reason at all. Just calculate the length once and store it, or use str[i] as the end condition.
You should also be aware that if your compiler uses signed characters, any character value above 127 will be considered negative (and used as a negative, i.e. out of bounds, array offset). You can avoid this by explicitly casting your character values to be unsigned char.

count number of times a character appears in an array?

i've been thinking for a long time and havent got anywhere with the program. i dont know where to begin. The assignment requires use of single function main and only iostream library to be used.
the task is to Declare a char array of 10 elements. Take input from user. Determine if array contains any values more than 1 times . do not show the characters that appears 1 time only.
Sample output:
a 2
b 4
..
a an b are characters. and 2 and 4 represents number of times they appear in the array B.
i tried to use nested loop to compare a character with all the character in array and incrementing a counter each time similer character id sound but unexpected results are occuring.
Here is the code
#include <iostream>
using namespace std;
void main()
{
char ara[10];
int counter=0;
cout<<"Enter 10 characters in an array\n";
for ( int a=0; a<10; a++)
cin>>ara[a];
for(int i=0; i<10; i++)
{
for(int j=i+1; j<10; j++)
{
if(ara[i] == ara[j])
{
counter++;
cout<<ara[i]<<"\t"<<counter<<endl;
}
}
}
}
Algorithm 2: std::map
Declare / define the container:
std::map<char, unsigned int> frequency;
Open the file
read a letter.
find the letter: frequency.find(letter)
If letter exists, increment the frequency: frequency[letter]++;
If letter no exists, insert into frequency: frequency[letter] = 1;
After all letters processed, iterate through the map displaying the letter and its frequency.
Here's one possible way you can solve this. I'm not giving you full code; it's considered bad to just give full implementations for other people's homework.
First, fill a new array with only unique characters. For example, if the input was:
abacdadeff
The new array should only have:
abcdef
That is, every character should appear only once in it. Do not forget to \0-terminate it, so that you can tell where it ends (since it can have a length smaller than 10).
Then create a new array of int (or unsigned, since you can't have negative occurrences) values that holds the frequency of occurence of every character from the unique array in the original input array. Every value should be initially 1. You can achieve this with a declaration like:
unsigned freq[10] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
Now, iterate over the unique array and every time you find the current character in the original input array, increment the corresponding element of the frequencies array. So at the end, for the above input, you would have:
a b c d e f (unique array)
3 1 1 2 1 2 (frequencies array)
And you're done. You can now tell how many times each characters appears in the input.
Here, I'll tell you what you should do and you code it yourself:
include headers ( stdio libs )
define main ( entry point for your app )
declare input array A[amount_of_chars_in_your_input]
write output requesting user to input
collect input
now the main part:
declare another array of unsigned shorts B[]
declare counter int i = 0
declare counter int j = 0
loop through the array A[] ( in other words i < sizeof ( A ); or a[i] != '\0' )
now loop as much as there is different letters in the array A
store the amount of letters in the B[]
print it out
Now there are some tricks applying this but you can handle it
Try this:
unsigned int frequency[26] = {0};
char letters[10];
Algorithm:
Open file / read a letter.
Search for the letters array for the new letter.
If the new letter exists: increment the frequency slot for that
letter: frequency[toupper(new_letter) - 'A']++;
If the new letter is missing, add to array and set frequency to 1.
After all letters are processed, print out the frequency array:
`cout << 'A' + index << ": " << frequency[index] << endl;

Getting a memory address in my array?

I'm writing a C++ application that has a user enter a 0 (zero) or a one (1) as input, then stores the numbers as an array and sorts them so that the zeros come first and the ones come last.
However, I think I'm getting a memory address in my array that's messing up the sorting operation.
The function that accepts input looks like this:
cout << "Please enter number " << i+1 << ":\n";
cin >> ar[i];
Then there's a function that's called that sorts the input and displays the sorted list:
sort_elements(ar, number);
... and that function looks like this:
void sort_elements(int ar[], long int num_elements) {
int temp_num;
num_elements -= 1; //since the array starts at 0
cout << "num_elements is " << num_elements << "\n";
for (int i=0; i < (num_elements/2); i++ ) {
if (ar[i] > ar[num_elements-i]) {
temp_num = ar[i];
ar[i] = ar[num_elements-i];
ar[num_elements-i] = temp_num;
}
}
cout << "Here's your neatly sorted list of numbers: \n";
for (int j=0; j <= num_elements; j++) {
cout << ar[j] << ", ";
}
cout << "\n";
}
For a five number input, starting with three "1"s, and ending with two "0"s, this results in an output that looks like this:
1, 0, 1, 1, 1892218304,
I'm assuming the 1892218304 is a memory address, that's messing up the input. Though I don't really know.
Can anyone figure out why my sort operation is getting messed up?
Thanks in advance.
Suggestion
Use vector and sort in standard library
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
int main()
{
std::vector<int> v;
for(int i=0; i < 10; i++)
{
v.push_back(i);
}
std::sort(v.begin(), v.end());
return 0;
}
The number you are seeing is not a memory address, but the value of the 4 bytes either immediately before or immediately after your array, interpreted as an int. Your code has an off-by-one error that causes an access to just outside the array. That much I suspect even though I don't have proof.
However, I can't find anything wrong with the code you posted that would cause it to access outside the array bounds.
Are you sure that num_elements has the correct value when this function is called?
Update to address the pastebin code
Things are going wrong already from the start:
int number;
int ar[number]
This is called a variable-length array and it's not legal in C90 or any flavor of C++. That your program compiles is probably "thanks to" a compiler extension... which helpfully raises a bug: the value of number is not initialized before the array is allocated.
You need to do one of the following:
declare ar as an array of constant size (a hard limit on the number of inputs you can accept)
dynamically allocate ar with new[] after number is entered from the user
(by far preferable) use an std::vector instead of an array
It looks to me like you're just getting an uninitialized value in your output.
Under the circumstances, the simplest "sorting" method is probably a counting sort -- i.e., count the number of 0's and the number of 1's the user enters, and then print out the appropriate number of 0's followed by the appropriate number of 1's.
As Tony said, your sorting algorithm is incorrect.
If we assume the following values:
ar[0] = 0
ar[1] = 1
ar[2] = 0
ar[3] = 1
ar[4] = 0
that gives us num_elements equal to 5.
Running this through your function as written, we get the following sorting behavior:
First pass, i = 0
ar[0] > ar[4] -> not true, so no switch
Secon pass, i = 1
ar[1] > ar[3] -> not true, so no switch
There is no third pass, as your for loop condition is met
i = 2
num_elements/2 = 2
2 is not less than 2
So based on your code, you didn't sort anything. This is the first issue.
Your print problem is interesting, based on what you have shown num_elements has been decremented by 1 at the top of your code snippet in your function - therefore the <= condition is correct and you should not be outside the bounds of your 'ar' array. Are you sure this is the exact code, or perhaps you did not copy it properly here and you are actually having a scoping issue?
(EDIT: Although the other answers suggesting using a built in sorting method via vectors, I'd suggest you still work your current implementation out to figure out WHY this is wrong, and what you need to do to fix it. You will not always have an available type that has built in sorting, so understanding the fundamentals is important for any young programmer.)
EDIT2: Based on the link you provided, you aren't properly defining your integer array. You are defining the array based on an uninitialized integer (int ar[number]) when number has not yet been initialized. You then read a value from the standard input to set number, and assume your array has been dynamically adjusted to be of the size read from cin. It does not work this way. Your entire loop is reading/writing outside the bounds of your array which is a big no-no. You want to read the number first, and then define your array based on the size read. - Looks like Jon beat me again.. BAH! :P
The last element being read and printed to the screen has never been written to. I think it's likely your function which accepts input has a fault, like maybe you have a line like you have here
num_elements -= 1; //since the array starts at 0
at the input function so that the first element you write to is at address 1. Then when you're reading them you read from address zero.
I kind of agree with Jim's point: Use the facilities in the C++ standard library to finish your task as much as possible.
Besides, I suggest you go through the algorithm all by yourself, manually, instead of letting the computer run it for you. Ever heard of the "Rubber Duck Debugging Method"? :-) Have a try.

How can I remove the leading zeroes from an integer generated by a loop and store it as an array?

I have a for loop generating integers.
For instance:
for (int i=300; i>200; i--)
{(somefunction)*i=n;
cout<<n;
}
This produces an output on the screen like this:
f=00000000000100023;
I want to store the 100023 part of this number (i.e just ignore all the zeros before the non zero numbers start but then keeping the zeros which follow) as an array.
Like this:
array[0]=1;
array[1]=0;
array[2]=0;
array[3]=0;
array[4]=2;
array[5]=3;
How would I go about achieving this?
This is a mish-mash of answers, because they are all there, I just don't think you're seeing the solution.
First off, if they are integers Bill's answer along with the other answers are great, save some of them skip out on the "store in array" part. Also, as pointed out in a comment on your question, this part is a duplicate.
But with your new code, the solution I had in mind was John's solution. You just need to figure out how to ignore leading zero's, which is easy:
std::vector<int> digits;
bool inNumber = false;
for (int i=300; i>200; i--)
{
int value = (somefunction) * i;
if (value != 0)
{
inNumber = true; // its not zero, so we have entered the number
}
if (inNumber)
{
// this code cannot execute until we hit the first non-zero number
digits.push_back(value);
}
}
Basically, just don't start pushing until you've reached the actual number.
In light of the edited question, my original answer (below) isn't the best. If you absolutely have to have the output in an array instead of a vector, you can start with GMan's answer then transfer the resulting bytes to an array. You could do the same with JohnFx's answer once you find the first non-zero digit in his result.
I'm assuming f is of type int, in which case it doesn't store the leading zeroes.
int f = 100023;
To start you need to find the required length of the array. You can do that by taking the log (base 10) of f. You can import the cmath library to use the log10 function.
int length = log10(f);
int array[length];
length should now be 6.
Next you can strip each digit from f and store it in the array using a loop and the modulus (%) operator.
for(int i=length-1; i >= 0; --i)
{
array[i] = f % 10;
f = f / 10;
}
Each time through the loop, the modulus takes the last digit by returning the remainder from division by 10. The next line divides f by 10 to get ready for the next iteration of the loop.
The straightforward way would be
std::vector<int> vec;
while(MyInt > 0)
{
vec.push_back(MyInt%10);
MyInt /= 10;
}
which stores the decimals in reverse order (vector used to simplify my code).
Hang on a second. If you wrote the code generating the integers, why bother parsing it back into an array?
Why not just jam the integers into an array in your loop?
int array[100];
for (int i=300; i>200; i--)
{
array[i]= (somefunction)*i;
}
Since the leading zeros are not kept because it represents the same number
See: convert an integer number into an array