c: my function does not count any words - c

I have been trying to make this function take an array of strings and count the number of words but I keep getting 0 as my answer i.e. it hasn't counted anything. I was wondering if anyone could help me out? I believe the logic is right( i could be wrong) but I am mostly really unsure about the way I would be iterating
thank you!!
Here is my code:
int fWords (char **array, int index) {
int number = 0;
int i = 0;
int in = 0;
int j = 0;
int length = 0;
while (i < index) {
length = strlen (array[i]);
for (j = 0; array[i][j] < length; j++) {
if (isspace(array[i][j]) != 0) {
in = 0;
}
else if (in == 0) {
in = 1;
number++;
}
}
i++;
}
return number;
}

You need to reset in after every run of the inner loop. Something like this
while (i < index) {
length = strlen (array[i]);
in = 0;
//^^^^^^^
for (j = 0; j < length; j++) {
if (isspace(array[i][j]) != 0) {
in = 0;
}
else if (in == 0) {
in = 1;
number++;
}
}
i++;
}

This condition is incorrect:
for (j = 0; array[i][j] < length ; j++)
// ^^^^^^^^^^^^^^^^^^^^
it should be simply
for (j = 0; j < length ; j++)
// ^^^^^^^^^^
This will fix the problem with zero.

Related

Removing duplicates in a C array

I am writing a program which determines the intersection of 2 integer arrays (size of 10 elements). I think I got every other parts covered except for sorting out duplicates. Does anyone know a way of checking duplicates without making a function or using an external C library?
#include <stdio.h>
#define SIZE 10
int main(void){
//Initialization
int array1[SIZE];
for (int i = 0; i < SIZE; i++)
{
printf("Input integer %d of set A: ", i + 1);
scanf("%d", &array1[i]);
}
int array2[SIZE];
for (int i = 0; i < SIZE; i++)
{
printf("Input integer %d of set B: ", i + 1);
scanf("%d", &array2[i]);
}
int intersection[SIZE];
for (int i = 0; i < SIZE; i++)
{
intersection[i] = '\0';
}
//Intersection check
for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
if (array1[i] == array2[j])
{
intersection[i] = array1[i];
break;
}
}
}
//duplicate check
int count = SIZE;
for (int i = 0; i < count; i++)
{
for (int j = i + 1; j < count; j++)
{
if (intersection[i] == intersection[j])
{
for (int k = j; j < count; i++)
{
intersection[k] = intersection[k + 1];
}
count--;
}
}
}
//printing set
for (int i = 0; i < SIZE ; i++)
{
//printf("%d\n", intersection[i]);
if (intersection[i] != '\0')
{
printf("%d\n", intersection[i]);
}
}
return 0;
}
In the code above i was trying one method although it didn't work and instead made the program stuck after inputting all the elements. I am open to other methods as long it doesn't require an external library to run. Thanks
As i see it now , in the third loop where you checking your duplicates i thing that you have to increese k not i :
for (int k = j; j < count; k++), also you must decrise the size of j in your code under the count--;.So your code for checking duplicates seems right but , you want the intersection of this two arrays you made , so you dont have to check for duplicates because in the array intersection[SIZE] you will put only one number from the two arrays, so you will not have duplicates .You should check for duplicates if you wanted to make the union of this two arrays .I make some changings to your code acording what you want to create and this code here find the intersection from two arrays.Try this and delete the duplicate check because that makes your code to run to infinity . One last thing your intersection check must be replace whith this :
//Intersection check
int i = 0, j = 0,k=0; // k is for the intersection array !
while (i < SIZE && j < SIZE) {
if (array1[i] < array2[j])
i++;
else if (array2[j] < array1[i])
j++;
else if(array1[i]==array2[j]) // if array1[i] == array2[j]
{
intersection[k]=array2[j];
//printf("intersection[%d]=%d\n",i,intersection[i]);
intersectCount++;
k++;
i++;
j++;
}
}
printf("intersectCount=%d\n",intersectCount);

How to implement check for distinctness

I have a function that reads in a line of ints as an array. I would like to implement an additional check for distinctness in the elements. I am already checking to make sure the array values don't equal the element number.
I tried nesting another for loop to run the check within the other check but I couldn't get it to work properly.
int readArray(int r[SIZE]) {
int i;
for (i = 0; i < SIZE; i++) {
scanf("%d", r + i);
// check for error element number
if (i == r[i]) {
printf("Error: element[%d] == %d\n", i, i);
return 0;
}
}
return 1;
}
I expect the function to output an error if there is a duplicate value or if the element number and value are equal.
My working solution is listed below I would like to make it a bit more concise is possible.
int i,j;
for (i = 0; i < SIZE; i++) {
scanf("%d", r + i);
// check for error
if (i == r[i]) {
printf("Error: Element[%d] == %d\n", i, i);
return 0;
}
}
// check for distinctness
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
if(i != j)//check indexes
{
if (r[i] == r[j])
{
printf("Two elements repeat to %d" , i);
printf("\nBad input exiting program");
return 0;
}
}
}
}
return 1;
}
Maybe it's not more concise, but if you want something more efficient, how about this:
...
for (i = 0; i < SIZE; i++)
{
for (j = i; j < SIZE; j++)
...
That way, you skip the comparisons you already made ;)
EDIT: Oh, even better:
...
for (j = i+1; j < SIZE; j++)
...
That way, you get rid of the:
if(i != j)

Scanning 2d array columns

I'm writing code to check whether each column in my array contains a column full of particular character (z), but there seems to be a flaw in my logic for indicating so. Are there any suggestions for modifying this?
check = 1;
for (i = 1; i < width; i++) {
for (j = 1; j <= column; j++) {
if (!((array[i+1][j] == 'z') && array[i][j] == array[i+1][j])){
check = 0;
printf("No match");
}
}
}
#include <stdio.h>
int main(void){
int width = 3, column = 3;
char array[3][3] = {
{'x','z','y'},
{'b','z','a'},
{'v','z','w'},
};
int i, j, check;
for(j = 0; j < column; j++){
check = 1;
for(i = 0; i < width; i++){
if(array[i][j] != 'z'){
check = 0;
break;
}
}
printf("columns %d is ", j+1);
if(check)
printf("match\n");
else
printf("no match\n");
}
return 0;
}

Out of bounds error in a loop

public static void bubbleSort(Farm a[], int n) {
String[] animals = getString(a);
for(int i = 0; i < n - 1; i++) {
boolean swapped = false;
for(int j = 0; j < n - 1 - i; j++) {
int c = animals[j].compareTo(animals[j+1]);
if(c > 0) {
swap(animals, j, j+1);
swapped = true;
}
}
if(!swapped)
break;
}
for (int i = 0; i < a.length; i++)
if(a[i] != null)
System.out.println(a[i].animal);
}
in int c = animals[j].compareTo(animals[j+1]); it is giving me an out of bounds error for some reason
It seems like n >= animals.length
Check boundary values in the for loops again

What is a neat way of breaking out of many for loops at once?

Suppose I need to break out of three or four nested for loops at once at the occurence of some event inside the innermost loop. What is a neat way of doing that?
what I do is use flags like this:
int i, j, k;
int flag1 = 0;
int flag2 = 0;
for (i = 0; i < 100; i++) {
for (j = 0; j < 100; j++) {
for (k = 0; k < 100; k++) {
if (k == 50) {
flag1 = 1;
flag2 = 1;
break;
}
}
if (flag1 == 1)break;
}
if (flag2 == 1)break;
}
I don't think this is particularly neat.
How would you accomplish the same thing? (w/o using jumps)
use goto. it's clean and simple.
Put all the loops in a function and just return instead of break.
If you're using Java, you can associate labels with each for block and then reference the label after a continue statement. For example:
outerfor:
for (int i=0; i<5; i++) {
innerfor:
for (int j=0; j<5; j++) {
if (i == 1 && j == 2) {
continue outerfor;
}
}
}
How would you accomplish the same thing? (w/o using jumps)
Why? Nothing is universally evil, and every put-upon tool has its uses (except gets()). Using goto here makes your code look cleaner, and is one of the only choices we have (assuming C). Look:
int i, j, k;
for (i = 0; i < 100; i++) {
for (j = 0; j < 100; j++) {
for (k = 0; k < 100; k++) {
if (k == 50) {
goto END;
}
}
}
}
END:
Much cleaner than all those flag variables, and it even shows more clearly what your code is doing.
Just a wee bit better.
int i, j, k;
int flag1 = 0;
int flag2 = 0;
for (i = 0; i < 100 && !flag2; i++) {
for (j = 0; j < 100 && !flag1; j++) {
for (k = 0; k < 100; k++) {
if (k == 50) {
flag1 = 1;
flag2 = 1;
break;
}
}
}
}
But if you really need to have those loops, then it makes sense explicitly declaring in each loop what conditions must hold for it to continue, for readability.
goto. This is one of the very few places where goto is the appropriate tool, and is usually the argument presented why goto isn't complete evil.
Sometimes, though, I do this:
void foo() {
bar_t *b = make_bar();
foo_helper(bar);
free_bar(b);
}
void foo_helper(bar_t *b) {
int i,j;
for (i=0; i < imax; i++) {
for (j=0; j < jmax; j++) {
if (uhoh(i, j) {
return;
}
}
}
}
The idea is that I get a guaranteed free of bar, plus I get a clean two-level break out of the switch via return.
If you absolutely don't want to use goto, set all loop conditions to false:
int i, j, k;
for (i = 0; i < 100; i++) {
for (j = 0; j < 100; j++) {
for (k = 0; k < 100; k++) {
if (k == 50) {
i = j = k = INT_MAX;
break;
}
}
}
}
note: a smart optimizing compiler will turn the contents of the if in a jump to the end of the outer-most loop
sometimes you can use trick like this:
for (i = 0; i < 100 && !flag2; i++) {
for (j = 0; j < 100 && !flag1; j++) {
for (k = 0; k < 100; k++) {
if (k == 50) {
k = 100;
i = 100;
j = 100;
}
}
}
}
or declare addition flag in your loop:
bool end = false;
for(int i =0; i < 1000 && !end; i++) {
//do thing
end = true;
}
it costs only a line but clean, I think.
justin
If premature completion of any cycle always means that you have to break the enclosing cycle as well, then you don't need any extra flags. The whole thing might just look as follows
int i, j, k;
for (i = 0; i < 100; i++) {
for (j = 0; j < 100; j++) {
for (k = 0; k < 100; k++) {
if (k == 50)
break;
}
if (k < 100) break;
}
if (j < 100) break;
}
In my experience, this is what is needed in majority of cases.
a little bit of silly self-documenting:
int i, j, k;
int done = 0;
for (i = 0; i < 100 && ! done; i++) {
for (j = 0; j < 100 && ! done; j++) {
for (k = 0; k < 100 && ! done; k++) {
if (k == 50) we_are(done);
}
}
}
//...
void we_are(int *done) {
*done = 1;
}
but really, you shouldn't have three nested for-loops. You should consider refactoring into different functions and improving your program's logic instead of doing this.
While I agree that sometimes goto really is the best solution, I think that any problem to which goto is the solution is a result of poor code.
Dividing by 0 is the surest method I know that will break you out of any number of loops. This works because the DIV assembly instruction doesn't like such silliness.
So, you can try this:
int i, j, k;
int flag1 = 0;
int flag2 = 0;
for (i = 0; i < 100; i++) {
for (j = 0; j < 100; j++) {
for (k = 0; k < 100; k++) {
if (k == 50) {
flag1 = 1;
flag2 = 1;
int z = 1 / 0; // we're outta here!!!
}
}
if (flag1 == 1)break;
}
if (flag2 == 1)break;
}
Getting back from the trap that happens on such events left as an exercise for the reader (it's trivial).
I'd do something like:
int i, j, k;
for (i = 0; i < 100; i++) {
for (j = 0; j < 100; j++) {
for (k = 0; k < 100; k++) {
if (k == 50) {
return;
}
}
}
}
If you are using GCC and this library, the break can accept the number of nested loops you want to exit:
int i, j, k;
for (i = 0; i < 100; i++) {
for (j = 0; j < 100; j++) {
for (k = 0; k < 100; k++) {
if (k == 50) {
break(3);
}
}
}
}
One way to do it is a state machine. But i would still use goto. It's much simpler. :)
state = 0;
while( state >= 0){
switch(state){
case 0: i = 0; state = 1; // for i = 0
case 1:
i++;
if (i < 100) // if for i < 100 not finished
state = 2; // do the inner j loop
else
state = -1; // finish loop
case 2: j = 0; state = 3; // for j = 0
case 3:
j++;
if (j < 100) // if j < 100 not finished
state = 4 // do the inner k loop
else
state = 1; // go backt to loop i
break;
case 4: k = 0; state = 5;
case 5:
k++;
if (k == 50){
state = -1;
break;
}
if (k < 100) // if k loop not finished
state = 5; // do this loop
else
state = 3; // go back to upper loop
break;
default : state = -1;
}
}

Resources