Identifying palindromes using stacks - c

I wrote the following code to check whether a string is a palindrome using stacks. I'm not getting the correct output whenever there are two same continuous characters in the string. For example, the code does say exe is a palindrome. But it says ee is not a palindrome.
int is_palindrome(char str[]) {
int j, top = -1;
char stk_item, s[30];
for (j = 0; j < strlen(str); j++)
s[top++] = str[j];
for (j = 0; j < strlen(str); j++) {
stk_item = s[--top];
if (str[j] != stk_item) return 0; // is not a palindrome
}
return 1; // is a palindrome
}
What may be the issue?

You confused the pre-increment and post-increment operators.
In C, x++ means "increment the value of x after this statement" and ++x means "first increment the value of x and then execute the statement."
The following code should work:
int is_palindrome(char str[]) {
int j, top = -1;
char stk_item, s[30];
for (j = 0; j < strlen(str); j++)
s[++top] = str[j];
for (j = 0; j < strlen(str); j++) {
stk_item = s[top--];
if (str[j] != stk_item) return 0;
}
return 1;
}

First of all, stacks work on Last-In First-Out technique. The last thing you insert into a stack is the first thing which gets out of it.
Basically speaking, there are two things you could do onto a stack, which are insert an object into the stack (typically called push) and remove an object from the stack (typically called pop).
In push technique, you assign the lowest available empty index to the object given. And thus it ought to be s[++top] = str[j]. Because you first increase the index and then fill it with an object.
In pop technique, you just reduce the highest filled index by 1. And thus it ought to be stk_item = s[top--]. Because you first say that the removed object is top and then reduce the index.

Related

Is there a way to extract the value of a variable used in a for loop at a certain point (C)?

I would like to know if there's a way for me to get the current value of "j" outside of the foor loop whenever the conditions is true. The variable "totalvalid" will tell me how many times the condition was met but I would also like to know the exact value of j when the condition is true so that I can use it at a later point. So I would want to extract the value of "j" whenever the "totalvalid = totalvalid +1" happens. Sorry if it looks messy. I'm new to coding and still have no idea how to make it cleaner. Thank you.
for(int j = 0; j < stringnumber; j++){
int valid = 0;
if(str[j][10] == '\0'){
for(int k = 0; k < 10; k++){
if(str[j][k] >= 'A' && str[j][k] <= 'Z'){
valid++;
}
}
if (valid == 10){
totalvalid = totalvalid + 1;
}
}
}
It seems that you want an array of numbers from that pass the condition.
My suggestion would be to make an array of ints, where you will keep these numbers.
Before loop:
int *array_of_valid_ints = (int *) calloc(stringnumber, sizeof(int)); // allocate the array
int number_of_valid_ints = 0;
Inside the if statement:
array_of_valid_ints[number_of_valid_ints] = j;
number_of_valid_ints++;
After the loop ends, you can check the good values with:
printf("This are the good ints: ")
for (int i = 0; i < number_of_valid_ints; i++) {
printf("%d ", array_of_valid_ints[i]);
}
printf("\n");
maybe you can define a variable before the loop as int j=0; then use a while loop instead of for.also remember to write j++ in the while loop.this way you can use the value of j outside of the loop too!

Arrays in C programming

I was working on the following 2d-array program to output this result shown in picture:
I can't seem to get the min value for the result and get it displayed in array form.
The code is below:
#include<stdio.h>
#define NUMROWS 2
#define NUMCOLS 3
//accessing elements of 2D array using pointers
int main(void){
const int table[NUMROWS][NUMCOLS]={{1,2,3},{5,6,7}};
int minvals[NUMROWS];
int i, j;
int *ptr = &table;
//accessing the elements of 2D array using ptr
printf("table values: min value\n");
for(int i=0;i<NUMROWS;i++){
for(int j=0;j<NUMCOLS;j++)
printf("%d ",*((ptr+i*NUMCOLS)+j));
printf("\n");
}
for(int i=0;i<NUMROWS;i++){
for(int j=0;j<NUMCOLS;j++)
printf("%d ",*((ptr+i*NUMCOLS)+j)<minvals[i]);
}
return 0;
}
The existence of minvals would imply that you are expected to calculate the minimum value of each 'row' of table before then moving on to printing. As it stands, had your program properly calculated the minimum values of each array, your printing would be rather out of order.
There's no need to do any tricky, manual pointer manipulation. Simple array subscription is much clearer.
Let's start simple and return to basics by looking at the way we find the minimum value in a one dimensional array, as it is the core of this problem.
To find the minimum value in an array we need a few things to start:
An array
The length of the array
An initial value to compare against
The array itself is obviously each subarray of table, and the length in this case is known to be NUMCOLS. Our initial value should either be INT_MAX (or another type-appropriate maximum constant found <limits.h>), such that every element in the array is equal to or less than our initial value, or a value from the array itself.
Often times we opt for the second option here, choosing the first element in the array as our initial value, and comparing it to the second and onward elements.
As such, finding the minimum value in a single 'row' would look like this
const int row[NUMCOLS] = { 9, 2, 5 };
int min = row[0];
for (int i = 1; i < NUMCOLS; i++)
if (row[i] < min)
min = row[i];
but since we want to find and record the minimum value of each 'row' in table, we're going to use a nested loop. Instead of the min variable from before, we store each value in the associated index of our minvals array.
for (i = 0; i < NUMROWS; i++) {
minvals[i] = table[i][0];
for (j = 1; j < NUMCOLS; j++)
if (table[i][j] < minvals[i])
minvals[i] = table[i][j];
}
When it comes time to print, we're going to repeat our nested loop. Our inner loop prints each element of each 'row' of table, and we end each iteration of the outer loop by printing the value found in minvals with the same index of our 'row'.
for (i = 0; i < NUMROWS; i++) {
for (j = 0; j < NUMCOLS; j++)
printf("%6d", table[i][j]);
printf(":%6d\n", minvals[i]);
}
Here's a working example.
#include <stdio.h>
#define NUMROWS 2
#define NUMCOLS 3
int main(void) {
const int table[NUMROWS][NUMCOLS] = {
{ 9, 2, 5 },
{ 3, -4, -12 }
};
int minvals[NUMROWS];
int i, j;
for (i = 0; i < NUMROWS; i++) {
minvals[i] = table[i][0];
for (j = 1; j < NUMCOLS; j++)
if (table[i][j] < minvals[i])
minvals[i] = table[i][j];
}
puts("Table value: minimum values");
for (i = 0; i < NUMROWS; i++) {
for (j = 0; j < NUMCOLS; j++)
printf("%6d", table[i][j]);
printf(":%6d\n", minvals[i]);
}
}
A good further exercise for you would be to compose the logic of the inner loop for finding minimum values into a more generic function. Its function signature would look like
int min(int *array, size_t length);
allowing it to work on arrays of varying sizes. Then our outer loop could be as simple as:
for (i = 0; i < NUMROWS; i++)
minvals[i] = min(table[i], NUMCOLS);
The line
int *ptr = &table;
is wrong, because &table is of type int (*)[2][3] (i.e. a pointer to the entire table), whereas ptr is a pointer to a single element. Also, your pointer is non-const, so it cannot point be made to point into a const array.
If you want ptr to point to a single int value, then you should declare it the following way:
const int *ptr = &table[0][0];
Also, you are reading the contents of the array minvals, although that array contains uninitialized data. This does not make sense and causes undefined behavior.
Instead of doing complex pointer arithmetic with the expression
*((ptr+i*NUMCOLS)+j))
you can simply write the following:
table[i][j]
That way, you do not need the pointer ptr and your code is simpler.

basic thing from a job interview - using linked list,arrays

I got this question on a job interview, and i could't solve it.
i think i was just really nervous because it doesn't look this hard.
Arr is a given integer array, size n. Sol is a given empty array,
size n.
for each i (i goes from 0 to n-1 ) you have to put in Sol[i] the index
in Arr of the closest elemnt appears on the left side, that is smaller
than Arr[i]. meaning: Sol[i]=max{ j | j < i; Arr[j] < Arr[i] }. if
the is no such index, put -1.
for example: Arr is [5,7,9,2,8,11,16,10,12] Sol is
[-1,0,1,-1,3,4,5,4,7]
time complexity: o(n) space complexity: o(n)
I tried to scan the array from the end to the start, but I didn't know how to continue.
I was asked to use only array and linked list.
I had 10 minutes to solve it, so guess it is not that hard.
thanks a lot!!
Note that for Arr[] with length < 2 there are trivial solutions. This pseudo code assumes that Arr[] has a length >= 2.
int Arr[] = {5,7,9,2,8,11,16,10,12};
int Sol[] = new int[9];
Stack<int> undecided; // or a stack implemented using a linked list
Sol[0] = -1; // this is a given
for(int i = Arr.length() - 1; i != 0; --i) {
undecided.push(i); // we haven't found a smaller value for this Arr[i] item yet
// note that all the items already on the stack (if any)
// are smaller than the value of Arr[i] or they would have
// been popped off in a previous iteration of the loop
// below
while (!undecided.empty() && (Arr[i-1] < Arr[undecided.peek()])) {
// the value for the item on the undecided stack is
// larger than Arr[i-1], so that's the index for
// the item on the undecided stack
Sol[undecided.peek()] = i-1;
undecided.pop();
}
}
// We've filled in Sol[] for all the items have lesser values to
// the left of them. Whatever is still on the undecided stack
// needs to be set to -1 in Sol
while (!undecided.empty()) {
Sol[undecided.peek()] = -1;
undecided.pop();
}
To be honest, I'm not sure I would have come up with this in an interview situation given a 10 minute time limit.
A C++ version of this can be found on ideone.com: https://ideone.com/VXC0yq
int Arr[] = {5,7,9,2,8,11,16,10,12};
int Sol[] = new int[9];
for(int i = 0; i < Arr.length; i++) {
int element = Arr[i];
int tmp = -1;
for(int j = 0 ;j < i; j++) {
int other = Arr[j];
if (other < element) {
tmp = j;
}
}
Sol[i] = tmp;
}

C: pointers to arrays, and destructive sorting

I wrote a brief piece of code. It has two functions: bubbleSort is a bubble sorting function (smallest to largest), and "int main" is used to test this piece of code with an int array of size 5.
I'd like this to destructively sort the array, and not simply pass through a copy. I have looked and looked, but I am still not entirely clear how this should work. What am I missing here?
#include <stdio.h>
void bubbleSort(int values[], int n);
int main(void) {
//set simple test array to make sure bubbleSort works
int arr[5] = {5,4,3,2,1};
//run it through function, and then print the now sorted array to make sure
bubbleSort(arr, 5);
printf("%i", arr);
return 0;
}
void bubbleSort(int values[], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0, hold = 0; j < n-i; j++) {
if (values[j] > values[j+1]) {
hold = values[j+1];
values[j+1] = values[j];
values[j] = hold;
}
}
}
return;
}
Note: The rest of my code looks sound to my amateur coding mind, but please give me pointers on what i can improve, what can be better, etc. I thought about using recursion for the bubble sort but i'm not yet as comfortable with C as I'd like to be to implement that. However if you have suggestions i'll be more than happy to read them.
thanks!
Looks like your function is sorting the array (although with some bugs) and you are just printing the result incorrectly. printf doesn't know how to print arrays. Instead, you need to use a loop to print each integer one at a time:
for(int i=0; i<5; i++){
printf("%d ", arr[i]);
}
printf("\n");
After changing this, the output is 1 2 3 4 5, as expected.
However, as mentioned in the comments, there are some bugs in the implementation of the bubblesort. For example, it tries to read elements from indedex after the end of the array, which is undefined behavior (namely, j+1 can be 5, which is out of bounds). I would recommend checking your book again to get a correct implementation of bubblesort.
There is one issue in you bubble sort code which must be fixed. Your inner loop has the issue:
/* for (int j = 0, hold = 0; j < n-i; j++) { */ // ISSUE here
for (int j = 0, hold = 0; j < n-i-1; j++) { // j < n-i-1 should be the condition
This is becasue, take the case of when i = 0, i.e. the first iterartion of outer for loop. This time, j < n - i will be true when j is one less than n - which is the last index of your array. Then you do comaprision between values[j] and values[j+1], where values[j+1] is clearly out of bound of your array. This will invoke undefined behavior, and your function will not give deterministic results.
Next improvement could be that your outer loop only needs to iterate from i = 0 till i < n-1, i.e. one times less than the total elements. You are interating one time more than needed.
Third, you can use a flag to keep track of weather you swap at least once in your inner loop. If there there are no swaps in inner loop then it means that array is already sorted. So at the end of each iteration of inner loop you can see if any swap was done, and if no swaps were done then break out of the outer loop. This will improve performance in cases where array is already almost sorted.
void bubbleSort(int values[], int n)
{
int swap; // To use as a flag
// for (int i = 0; i < n; i++) {
for (int i = 0; i < n-1; i++) {
swap = 0; // set swap flag to zero
// for (int j = 0, hold = 0; j < n-i; j++) {
for (int j = 0, hold = 0; j < n-i-1; j++) {
if (values[j] > values[j+1]) {
hold = values[j+1];
values[j+1] = values[j];
values[j] = hold;
swap = 1; // swap was done
}
}
if (swap == 0) // If no swap was done
break; // Means array already sorted
}
return;
}
And, although not related to your sorting function, as others have pointed out, printf("%i", arr); is wrong, and will invoke undefined behavior because you are using a wrong format specifier in printf. It seems like you are trying to print the array. For that you can do:
// printf("%i", arr);
for (int i = 0; i < 5; i++)
printf("%d ", arr[i];)
printf("\n");
Your code already sorts the array in-place - although there is a bug in it. I'll address the subject of the question only (in-place sorting of an array in C) as comments have already highlighted the bugs with the sort function.
The print-out of the result is incorrect though as it tries to print the arr pointer as an integer:
sort.c:10:18: warning: format specifies type 'int' but the argument has type 'int *' [-Wformat]
printf("%i", arr);
~~ ^~~
1 warning generated.
However changing this to:
for (int i = 0; i < 5; i++)
printf("%i", arr[i]);
fixes the problem with the output.
Perhaps your confusion comes from how arrays are actually a syntactic way to access pointers in C. arr is a pointer. arr[1] is the same as *(arr + 1) (the contents of the pointer arr + 1 using pointer arithmetic, which increments the pointer by the sizeof the type). So when you pass arr into the function, you are passing a pointer to the existing array, then you are modifying its contents, sorting the array in-place.

Terminating loops

So I have a function that is supposed to find the mode of a set of data input by a user. I believe there is a problem with how I terminate my loops, using the '\0' character, but I'm not sure. Even if that is the problem, I don't know how to fix it. Any advice appreciated.
int mode(int input[]){
int array[70]={0},i=0,j=0,i2=0,j2=0;
while (input[i]!='\0'){
j=input[i];
array[j]=array[j]+1;
i++;
}
while (array[i2]!='\0'){
if (array[i2]>j2){
j2=array[i2];
i2++;
}
else{
i2++;
}
}
return j2;
}
Generally speaking, you will know how many entries are in the user's input, so your mode() function will be better off as int mode(int num, int input[]). Your code assumes that the values in the input array will be in the range 1..69 without checking. It is odd (though technically legitimate) to write '\0' instead of 0. Your second loop stops when it comes across a zero count. It does that immediately because array[0] is never set to anything other than zero.
I'd write the loops as for loops, whether using a 'zero as sentinel' or 'explicit count'.
int mode(int input[])
{
int array[70];
for (int i = 0; input[i] != 0; i++)
{
int value = input[i];
if (value > 0 && value < 70)
array[value]++;
}
int m_value = array[1];
for (int j = 2; j < 70; j++)
{
if (array[j] > m_value)
m_value = array[j];
}
return m_value;
}
The only difference for the counted version that I recommend is changing the termination condition of the first loop from input[i] != 0; to i < num;.

Resources