Comparing nodes of a list with a string array - c

If i have an array that contains some char such as [a,b,c] and i have another array that contains the respective frequency of each char such as [2,1,1]. I would like to now go through a linked list which has nodes which have some string to see if they also have the chars i have in my original array with same frequency.
My approach
I was thinking i need
One loop that will start at index 0 of original array and another loop inside that will check all nodes for that string and if my temp pointer hits null it means all of them have it and if not then they don't and i move on to the next one. However i am not sure how to quite implement this approach as i am very new to c and also i was wondering is it possible to do this in O(N) TIME as my approach would be O(N2).
Sample Output: i apologize for the confusion
so if you have 3 nodes and each has a char array containing "nba" "tba" "rba"
the output should then return b a . since both them appear equal number of times in each node.

So you start both your char array and freqarray at index 0 and then check all the nodes for strings matching the same frequency of a character . I presume you use some kind of function to return frequency of particular char in a string .
Also your problem requires you to go through all of the nodes hence O(N^2) is implied.

Related

How to replace a specific character in an array with two characters

So I just came back from a job interview and one of the questions I had to face with was :
"Given an array of characters and three characters for example :
Array : [a,b,c,z,s,w,y,z,o]
Char 1: 'z'
Char 2 : 'R'
Char 3 : 'R'
Your goal is to replace each 'z' in the array to become two R characters within O(N) time complexity.
so your input will be Array : [a,b,c,z,s,w,y,z,o]
and your output array will be : [a,b,c,R,R,s,w,y,R,R,o]
assume that there is no 'R' in the array before.
You are not allowed to use other arrays or other variables.
The algorithm should be in-line algorithm.
Your final array must be a characters array."
My solution was within O(N^2) time complexity but there is a solution within O(N) time complexity .
The interview is over but I am still thinking about this problem, Can anyone help me to solve this ?
First scan the input to count how many occurrences of char 1 exist. This has a linear time complexity.
From that you know that the length of the final array will be the input length + the number of occurrences.
Then extend the array to its new length, leaving the new slots empty (or whatever value). The exact nature of the operation depends on how the array data structure is implemented. This can surely be done with at worst a linear time complexity.
Use two indexes, i and j, where i references the last character of the input array and j references the very last index in the array (potentially to an empty slot).
Start copying from i to j each time decreasing the values of these indices with one. If you copy the matching letter, then duplicate the copied character to j again, and only reduce j. This has again a linear time complexity.
The algorithm will end with both i and j equal to -1.
Do two iterations.
First, count the number of char1s ('z' in your example).
Now you know how long your array should be at the end: array.size() + num_char1s
Then, go from last to first with input and output iterators. If the element is char1, insert to the end iterator the new chars, otherwise - just copy.
Pseudo code:
num_char1s = 0
for x in array:
if x == char1:
num_char1s++
// Assuming array has sufficient memory already allocated.
out_iterator = num_char1s + size - 1
in_iterator = size - 1
while (in_iterator >= 0):
if (array[in_iterator] == char1):
array[out_iterator--] = char3
array[out_iterator--] = char2
else:
array[out_iterator--] = array[in_iterator]
in_iterator--
In your question, two things are very important.
can't use new variable
can't use new array
So, we must need to use given array.
First we will increase our given array size double. why? Cause at most our new array size = given_array_size*2 (if all characters = char 1)
Now we will shift our given array n times right, where n= given_array_size.
Now we will iterate our array from the new shifted position = n. iterate i=n to 2*n-1
We will take j=0, which will write new array. if we found char 1, we will
make array[j++]=char 2 and array[j++]=char 3.
But if a character is not 'z', we simply don't do anything. array[j++]=array[i]
At last 0 to j-1 is the right answer.
Complexity: O(n)
No new variable and array needed

How to write two strings to a file in C and sort it?

i'm programming this Maze game in C. I have the strings name[15] and score[15]so when I print them the output is this "John 1000" so I need to write that output into a file every time the user finish the game and then if another user gets a higher or lower score sort it so the file should end up like this in 3 times running the game and finishing it:
Clark 25000
John 23000
Louis 21000
What you should do is, each time a user finishes the game, you load the dynamicly allocated array, you sort it, then rewrite the file.
First take a structure s with char str1[], char str2[] and struct s *next as fields. (For making linked list)
Since ' ' and '\n' are the delimiting characters here, read the first string till we hit ' ' into s->str1[] and in second string s->str2[] till we hit '\n' (After doing malloc() of the structure s)
So when new entry is to be added, we traverse through the list. If first node value (atoi(s->str2[]) is less than new entry's value; make the new entry as first node. If not, then traverse till linked list's node's value is less than the new entry's value.
So basically, we sort it while inserting into the list itself (descending wrt to values).
so if (a)6,(b)2,(c)7,(d)8,(e)5,(f)1 are the values we could sort like below:
1. (a)6->NULL
2. (a)6->(b)2->NULL
3. (c)7->(a)6->(b)2->NULL
4. (d)8->(c)7->(a)6->(b)2->NULL
5. (d)8->(c)7->(a)6->(e)5->(b)2->NULL
6. (d)8->(c)7->(a)6->(e)5->(b)2->(f)1->NULL

Number sequences length, element first and last indexes in array

Im beginner in programming. My question is how to count number sequences in input array? For example:
input array = [0,0,1,1,1,1,1,1,0,1,0,1,1,1]
output integer = 3 (count one-sequences)
And how to calculate number sequences first and last indexes in input array? For example:
input array = [0,0,1,1,1,1,1,1,0,1,0,1,1,1]
output array = [3-8,10-10,12-14] (one first and last place in a sequence)
I tried to solve this problem in C with arrays. Thank you!
Your task is a good exercise to familiarize you with the 0-based array indexes used in C, iterating arrays, and adjusting the array indexes to 1-based when the output requires.
Taking the first two together, 0-based arrays in C, and iterating over the elements, you must first determine how many elements are in your array. This is something that gives new C programmers trouble. The reason being is for general arrays (as opposed to null-terminated strings), you must either know the number of elements in the array, or determine the number of elements within the scope where the array was declared.
What does that mean? It means, the only time you can use the sizeof operator to determine the size of an array is inside the same scope (i.e. inside the same block of code {...} where the array is declared. If the array is passed to a function, the parameter passing the array is converted (you may see it referred to as decays) to a pointer. When that occurs, the sizeof operator simply returns the size of a pointer (generally 8-bytes on x86_64 and 4-bytes on x86), not the size of the array.
So now you know the first part of your task. (1) declare the array; and (2) save the size of the array to use in iterating over the elements. The first you can do with int array[] = {0,0,1,1,1,1,1,1,0,1,0,1,1,1}; and the second with sizeof array;
Your next job is to iterate over each element in the array and test whether it is '0' or '1' and respond appropriately. To iterate over each element in the array (as opposed to a string), you will typically use a for loop coupled with an index variable ( 'i' below) that will allow you to access each element of the array. You may have something similar to:
size_t i = 0;
...
for (i = 0; i< sizeof array; i++) {
... /* elements accessed as array[i] */
}
(note: you are free to use int as the type for 'i' as well, but for your choice of type, you generally want to ask can 'i' ever be negative here? If not, a choice of a type that handles only positive number will help the compiler warn if you are misusing the variable later in your code)
To build the complete logic you will need to test for all changes from '0' to '1' you may have to use nested if ... else ... statements. (You may have to check if you are dealing with array[0] specifically as part of your test logic) You have 2 tasks here. (1) determine if the last element was '0' and the current element '1', then update your sequence_count++; and (2) test if the current element is '1', then store the adjusted index in a second array and update the count or index for the second array so you can keep track of where to store the next adjusted index value. I will let you work on the test logic and will help if you get stuck.
Finally, you need only print out your final sequence_count and then iterate over your second array (where you stored the adjusted index values for each time array was '1'.
This will get you started. Edit your question and add your current code when you get stuck and people can help further.

algorithm on sorting array of pointers to strings in O(n)

This is my algorithms assignment, and I do not know how to proceed.
Given an array A of m strings, where different strings may have different numbers of
characters, but the total number of characters over all the strings in the array is n. Show
how to sort the strings in O(n) time. Note that the desired order here is the standard
alphabetical order; for example, a < ab < b.
More technically speaking, A is an array of pointers each pointing to a string (which is
another array of characters); you can think about how strings are used in C. Also, we
assume that each character can be viewed as an integer ranging from 0 to 255.
Since this is an assignment I won't provide a complete answer, merely some ideas on how to proceed.
Since the strings can be any length you need to use an O(n) sorting algorithm.
One such algorithm is bucket sort.
So how do we arrange the buckets for variable length strings?
Create 256 buckets for the first character.
Let each bucket have a counter + a set of 256 buckets for the second character and so on.
Important note: Don't create any bucket set until you need to or the memory consumption will be infinite. Let an empty bucket set be NULL
When we have the bucket system set up. How do we sort a word into the bucket system?
Let's say we have the word Yes.
First character is Y so we go to the top level bucket set. The set is NULL so we create the top level and select bucket 'Y'.
Next character is e. The bucket set under Y is NULL so we create the set and select bucket 'e'.
Next character is s. The bucket set under Ye is NULL so we create the set and select bucket 's'.
The string ends. Increase the count for the current bucket Y->e->s.
Note that the task will be simpler if you use unsigned char, because then you can use the value directly as an index into an array of length 256.
The bucket struct could look like this:
typedef struct bucket {
int count;
struct bucket *next; // points to NULL or array of 256 buckets.
} bucket;
Time Complexity:
The maximum amount of work for each character is:
end of string check + NULL check + ((allocation and initialization of array of 256 buckets (I would use calloc for this) or (increase one bucket count)) + increase loop variable.
Memory Usage
Here comes the disadvantage of bucket sort. It uses a lot of memory if you need many buckets, and this solution will use quite a number.
You may think about String as about number in 255 basis. So, if distribution is uniform, then bucket sort would give linear time; also radix sort is linear, but you need some preparations before sort (to transform String into number).

Limit input data to achieve a better Big O complexity

You are given an unsorted array of n integers, and you would like to find if there are any duplicates in the array (i.e. any integer appearing more than once).
Describe an algorithm (implemented with two nested loops) to do this.
The question that I am stuck at is:
How can you limit the input data to achieve a better Big O complexity? Describe an algorithm for handling this limited data to find if there are any duplicates. What is the Big O complexity?
Your help will be greatly appreciated. This is not related to my coursework, assignment or coursework and such. It's from the previous year exam paper and I am doing some self-study but seem to be stuck on this question. The only possible solution that i could come up with is:
If we limit the data, and use nested loops to perform operations to find if there are duplicates. The complexity would be O(n) simply because the amount of time the operations take to perform is proportional to the data size.
If my answer makes no sense, then please ignore it and if you could, then please suggest possible solutions/ working out to this answer.
If someone could help me solve this answer, I would be grateful as I have attempted countless possible solution, all of which seems to be not the correct one.
Edited part, again.. Another possible solution (if effective!):
We could implement a loop to sort the array so that it sorts the array (from lowest integer to highest integer), therefore the duplicates will be right next to each other making them easier and faster to be identified.
The big O complexity would still be O(n^2).
Since this is linear type, it would simply use the first loop and iterate n-1 times as we are getting the index in the array (in the first iteration it could be, for instance, 1) and store this in a variable names 'current'.
The loop will update the current variable by +1 each time through the iteration, within that loop, we now write another loop to compare the current number to the next number and if it equals to the next number, we can print using a printf statement else we move back to the outer loop to update the current variable by + 1 (next value in the array) and update the next variable to hold the value of the number after the value in current.
You can do linearly (O(n)) for any input if you use hash tables (which have constant look-up time).
However, this is not what you are being asked about.
By limiting the possible values in the array, you can achieve linear performance.
E.g., if your integers have range 1..L, you can allocate a bit array of length L, initialize it to 0, and iterate over your input array, checking and flipping the appropriate bit for each input.
A variance of Bucket Sort will do. This will give you complexity of O(n) where 'n' is the number of input elements.
But one restriction - max value. You should know the max value your integer array can take. Lets say it as m.
The idea is to create a bool array of size m (all initialized to false). Then iterate over your array. As you find an element, set bucket[m] to true. If it is already true then you've encountered a duplicate.
A java code,
// alternatively, you can iterate over the array to find the maxVal which again is O(n).
public boolean findDup(int [] arr, int maxVal)
{
// java by default assigns false to all the values.
boolean bucket[] = new boolean[maxVal];
for (int elem : arr)
{
if (bucket[elem])
{
return true; // a duplicate found
}
bucket[elem] = true;
}
return false;
}
But the constraint here is the space. You need O(maxVal) space.
nested loops get you O(N*M) or O(N*log(M)) for O(N) you can not use nested loops !!!
I would do it by use of histogram instead:
DWORD in[N]={ ... }; // input data ... values are from < 0 , M )
DWORD his[M]={ ... }; // histogram of in[]
int i,j;
// compute histogram O(N)
for (i=0;i<M;i++) his[i]=0; // this can be done also by memset ...
for (i=0;i<N;i++) his[in[i]]++; // if the range of values is not from 0 then shift it ...
// remove duplicates O(N)
for (i=0,j=0;i<N;i++)
{
his[in[i]]--; // count down duplicates
in[j]=in[i]; // copy item
if (his[in[i]]<=0) j++; // if not duplicate then do not delete it
}
// now j holds the new in[] array size
[Notes]
if value range is too big with sparse areas then you need to convert his[]
to dynamic list with two values per item
one is the value from in[] and the second is its occurrence count
but then you need nested loop -> O(N*M)
or with binary search -> O(N*log(M))

Resources