Loop Iteration Efficient - loops

You have a loop that iterates over 1,000 items. You want to add a newline to every four items. The items are in an array structure that have numeric index starting at 0. How do you do it?

FWIW:
for (int i = 0; i < list.size(); ++i) {
// you want to 'do it' with list[i] here
if (0 == (i+1)%4))
{
// 'you want to add a new line' here
}
}

Just in case what you are really trying to ask is "How do I print these items, four to a line?" here's one way
int nOnLine = 0;
for (i = 0; i < 1000; i++){
// print item i
nOnLine++;
if (nOnLine >= 4){
// print newline
nOnLine = 0;
}
}
if (nOnLine > 0){
// print newline
nOnLine = 0;
}

for (int i = 0; i < list.size(); i += 4) {
// add to the item
}
The above iterates over every fourth item instead of every single item.

for(i=3;i<len;i=i+4) { // where len is the length of your array
ary[i]+='\n'; // use string append operator of your language.
}
which will add a newline to every fourth item, i.e. items 3, 7, 11, etc.
EDIT
Changed to fulfill the OP's criteria.

Related

Check if a string is included in an array and append if not (C)

I have 2 arrays, one called 'edges' which contains a list of city names and another called cityNames which is initialised as an empty string.
What I would like to do is move through the edges array element by element and see if it is included in the cityNames array. If it is, move onto the next element in edges, if it isn't, append the value to the cityNames array.
The code below adds the edges[i].startCity to the cityNames array but it does not check for duplicates and I can't figure out why.
for (int i = 1; i < noEdges; i++) {
for (int j = 0; j < noCities; j++) {
if(strcmp(edges[i].startCity, cityNames[j].cityName) != 0) {
strcpy(cityNames[i].cityName, edges[i].startCity);
}
}
noCities += 1;
}
Thanks in advance
I will assume that:
edges is an array of structures of a known length noEdges, each structure containing a string (either a char pointer or a char array)
cityNames is an array of structures for which the size is at least the number of distinct name (it could be noEdges or the size of the edges array)
the cityNames structure contain a char array element for which the size is at least the longest name + 1 (+1 for the terminating null)
Then the following code could give the unique names:
noCity = 0;
for (int i = 0; i < noEdges; i++) {
int dup = 0; // expect edges[i].startCity not to be a duplicate
for (int j = 0; j < noCities; j++) {
if(strcmp(edges[i].startCity, cityNames[j].cityName) == 0) {
dup = 1; // got a duplicate
break; // no need to go further ...
}
}
if (dup == 0) { // not a duplicate: add it to cityNames
strcpy(cityNames[noCities].cityName, edges[i].startCity);
noCities += 1; // we now have one more city
}
}
}
A good idea to start with would be to ditch working with strings if you can (or at least manipulate strings when actually needed).
You could start off by assigning each city name a number, that way you have an array of ints which is quicker and easier to work with.
Scanning for duplicates becomes trivial as you would now only be comparing numbers.
When you need to display the actual text on screen or write the city names to file, you could use the indexes associated with the city names to retrieve the appropriate textual representation of the index. You could then replace the data type of your cityNames[] to ints. This makes each 'node' which the 'edges' connect a number instead of text.
char* actualCityNames[n]; //array holding all city names with duplicates, could be a file also
char* indexedCityNames[n];//array with indexed cities (in order of appearance in actualCityNames, i.e. not alphabetical order)
//indexedCityNames will most likely not use up N slots if duplicates occur
//this is why there is a second counter for the size of indexed cities
int indexedCount = 0;//number of unique city names
int duplicates = 0;
//loop for actualCityNames slots
for(int i=0; i<n; i++){
//loop for indexedCityNames
for(int j=0; j<indexedCount; j++){
//strcmp returns 0 if both strings are the same
if(strcmp(actualCityNames[i],indexedCityNames[j]) == 0){
//duplicate found, mark flag
duplicates = 1;
}
}
if(!duplicates){
strcpy(indexedCityNames[indexedCount],actualCityNames[I]);
indexedCount++;
}
duplicates = 0;
}
Your code snippet does not check for duplicates because in the inner loop the if statement appends startCity as soon as a first cityName is encountered that is not equal to the current startCity.
Moreover in this statement
strcpy(cityNames[i].cityName, edges[i].startCity);
^^^
there is used an incorrect index.
And the variable noCities shall be incremented only when a new startCity is appended.
Also the outer loop should start from the index equal to 0.
Rewrite the loops the following way
int noCities = 0;
for ( int i = 0; i < noEdges; i++ ) {
int j = 0;
while ( j < noCities && strcmp(edges[i].startCity, cityNames[j].cityName) != 0 ) {
++j;
}
if ( j == noCities ) strcpy(cityNames[noCities++].cityName, edges[i].startCity);
}

How do I replace all occurrences in an array with another array in C

I want to replace all occurrences in an array (string) with another array.
I have a code that:
stores the string in an array in which the replacing is to take place output[],
another array that stores the string to be searched for as replace[] and a third array called toBeReplacedBy and the replacing of the first occurrence works just fine but it skips the other occurrences in the output
for example:
replace[]:
abc
toBeReplacedBy[]:
xyz
output[]:
abcdefabc
becomes
xyzdefabc
but it should become:
xyzdefxyz
I suspect the problem lies with the replacer code :
//the replacer
for (i = 0; i<80; i++) {
if (output[i] == replace[i])
output[i] = toBeReplacedBy[i];
}
//debug purpose
puts("output[]:\n");
puts(output);
return 0;
}
What have I done wrong here and how could I get it to replace all occurrences in the array.
please be aware that I only wish to use stdio.h to do this
thabks in advance
Never iterate further than the array length. This leads to undefined and possibly dangerous behaviour. If you only expect strings, use something like:
int i = 0;
while(output[i] != '\0')
{
// your logic here
i++;
}
Additionally you want to check for concurrent appearances of the same characters. But in your code you only check the first three characters. Everything after that is undefinded behaviour, because you cannot know what replace[3] returns.
Something similar to this could work:
int i = 0;
int j = 0;
int k;
while(output[i] != '\0')
{
if (output[i] == replace[j])
j++;
else
j = 0;
// replace 3 with the array length of the replace[] array
if (j == 3)
{
for(k = i; j >= 0; k-- )
{
output[k] = toBeReplacedBy[j]
j--
}
j = 0;
}
i++;
}
But please check the array boundaries.
edit: Additionally as Nellie states using a debugger would help you to understand what went wrong. Go through your program step by step and look how and when values change.
First advice is to try to debug your program if it does not work.
for (i = 0; i<80; i++) {
if (output[i] == replace[i])
output[i] = toBeReplacedBy[i];
}
There are two problems in this loop.
The first is that are iterating until i is 80. Let's look what happens when i becomes 3. output[3] in case of abcdefabc is d, but what is replace[3]? Your replacement array had only 3 letters, so you have to go back in the replacement array once you finish with one occurrence of it in the original string.
The second is that you check letter by letter.
Say you original array, which you named output somehow was abkdefabc, first three letters do not match your replacement string, but you will check the first two letters they will match with the replacement's first two letters and you will incorrectly change them.
So you need to first check that the whole replacement string is there and only then replace.
You should use strlen() to know length of your array or iterate until you reach the end of a your array ('\0').
'\0' and strlen are only available for array of char.
Your loop should looks like this :
int i = 0;
int len = strlen(my_string);
while (i < len)
{
//logic here
i = i + 1;
}
OR
int i = 0;
while (my_string[i] != '\0')
{
// logic here
i = i + 1;
}

How to simplify an extensive C if statement?

I am wondering what the best way is to approach this problem. I have a randomizing function set up that takes 8 strings as input and outputs a random one of them. I would like this randomizer to disregard all strings which have no value. For example, if I have strings text#, where # is 1-8, and let's say text5 and text7 have no text, then I want the randomizing function to check if any to use only use text#, where # is 1-8 but not 5 or 7.
Yikes! Put the strings in an array instead of having 8 different variables. Then use a for loop.
Count the list for valid strings.
Form random number (rand() % Count).
Find the matching string.
Sample code
int StringCount = 8;
char *String[StringCount];
// populate `Sting` somehow
// count valid strings
int Count = 0;
for (int i=0; i<StringCount; i++) {
if (ValidString(String[i])) Count++;
}
if (Count == 0) Handle_NoGoodStrings();
int random_number = rand()%Count;
int i;
for (i=0; i<StringCount; i++) {
if (ValidString(String[i])) {
if (Count == random_number) {
break;
}
}
}
// String[i] is the string
Put the strings in an array
Choose a random index into the array, using your random function
Use code similar to:
int i;
for (i = index; i != index; i = (i+1) % numitems)
{
/* check we have a string and it isn't empty */
if (strings[i] && *strings[i])
return strings[i];
}
return NULL;
assuming index is your random number between 0 and numitems -1.

How to check if current index is last index in array?

How do I say?
for (i = 0; i < arraySize; i++)
{
if (someArray[i + 1] !NULL)
{
//do this
}
else
{
//do something else
}
}
In other words, I want to check if the current index is the last index in the array. The current code is my best guess but it isn't working.
EDIT: It is an integer array and i less than arraySize not 0
EDIT 2: The code inside my for loop is more complicated than the example above but I can't paste all the code as it is top secret atm. I have many nested if statements. if(i==arraySize-1) helped me to solve the problem. Thanks.
Following line will give you count of items in your array:
count = sizeof (intMyArray)/sizeof(intMyArray[0]);
if you know arraySize then:
if(i==arraySize-1){
//last element of array
}
Size of Array:
int array[20], i;
// ...
// fill array
// ...
int sz = sizeof(array)/sizeof(int);
for(i=0; i < sz;i++) {
if(array[i] != 0x0) {
// do something
}
}

C remove duplicate char from array

Somewhere in my program I get these outputs:
ee
or:
thht
Basically I want to remove the duplicates to obtain e or th. I got this code:
j = 0;
for (i = 1; i < strlen(erros); i++)
{
if (erros[j] != erros[i])
{
erros[j+1] = erros[i];
j++;
}
}
This code gives me e and tht. If in the first case its OK, in the second its not. I believe it is due because I don't have a sorted array.
Is there a way, without sorting the array and using the above code, to obtain the desired output?
You can create an array of flags, one for each possible character value. The first time you encounter a particular character value, set the flag. The next time you encounter that value, the flag will be set, indicating that you can remove that character.
Along the lines of (untested):
int flags[1 << CHAR_BIT];
memset(flags, 0, sizeof(flags));
j = 0;
for (i = 0; i < strlen(erros); i++)
{
erros[j] = erros[i]; // Always copy, it's simpler
if (!flags[erros[i]])
{
j++;
}
flags[erros[i]] = 1; // Always set the flag, it's simpler
}
erros[j] = '\0';
Note: You are forgetting to set the NULL terminator in your string.

Resources