#include <stdio.h>
#include <string.h>
typedef struct {
char name[11];
int score;
} report;
int main() {
int n = 3;
report student[n];
for (int i = 0; i < 3; i++) {
scanf("%[^\#]#%d", student[i].name, &student[i].score);
}
// Input name that we search.
char search[11];
scanf("%s", search);
// bubble sort
for (int a = 0; a < n - 1; a++) {
for (int b = 0; b < n - 1 - a; b++) {
if (student[b].score < student[b+1].score) {
report temp;
strcpy(temp.name, student[b].name);
temp.score = student[b].score;
strcpy(student[b].name, student[b+1].name);
student[b].score = student[b+1].score;
strcpy(student[b+1].name, temp.name);
student[b+1].score = temp.score;
}
}
}
// binary search
int left = 0;
int right = n - 1;
int middleIndex;
int rank;
while (left <= right ) {
middleIndex = (int)(left + right) / 2;
if (strcmp(student[middleIndex].name, search) == 0) {
rank = middleIndex+1;
break;
} else if (strcmp(student[middleIndex].name, search) > 0) {
left = middleIndex + 1;
} else if (strcmp(student[middleIndex].name,search) < 0) {
right = middleIndex - 1;
}
}
// Rank of the student's name that we search.
printf("%d", rank);
return 0;
}
I want to create a program that will return a student ranking (from 3 students). The fourth line is the name that we searched. I put all the user input into a struct and sort it in descending order to represent students ranking. But the problem is, when it reach the binary search, it always return unexpected value. Could you guys help me solve the problem?
Sample Input :
Jojo#40
Ray#60
Liz#80
Jojo -> name that we searched.
""" [ {Liz, 80}, {Ray, 60}, {Jojo,40} ] """
Output : 3
At least one problem is that your names (except the first) will have a newline as the first character. That newline was left in the input stream when scanning the score.
Consequently your string compare doesn't work.
Add this
for (int a = 0; a < 3; a++) printf("|%s|\n", student[a].name);
printf("|%s|\n", search);
just after scan of search and you get the output:
|Jojo|
|
Ray|
|
Liz|
|Jojo|
As you can see there are "unexpected" newlines in front of both "Ray" and "Liz"
To solve that add a space here
scanf(" %[^\#]#%d"
^
space
As noted by #EricPostpischil in a comment, sorting by score and doing binary search by name makes no sense. The sort and the search must be based on the same.
BTW: When sorting arrays use qsort
else {
masterNum[3] = guess % 10; //checks integers in their respective positions
masterNum[2] = ((guess - guess%10)/10)%10;
masterNum[1] = ((guess - guess % 100)/100)%10;
masterNum[0] = (guess - guess % 1000)/1000;
masterDigit(guess, masterNum);
}
//}
//This method determines the total number of correct digits but not
//necessarily in the correct position
public static int masterDigit (int [] guess,int [] code) //int [] guess
{
int i,j,k,number;
int [] tempGuess = new int [4]; //an array to hold a copy of a code
boolean found;
number = 0;
for(k=0; k<4; k++) //copies code to tempGuess so code
//doesn't get changed (you can't just assign code to tempGuess)
tempGuess[k] = code[k];
for(i = 0; i < 4; i++)
{
j=0;
found = false;
while(j < 4 && found == false) // a while loop instead of a
// for loop so duplicates are only counted once
{
if(guess[i] == tempGuess[j])
{
found = true;
tempGuess[j] = -1; // fills up tempGuess with an impossible
// value so that index only gets
// counted once
number++;
}
j++;
}
}
return number;
}
This code is for a Mastermind game with integers. Upon running through the compiler, there is an error saying that integer "guess" cannot be converted to an array. How can I get my guess (defined as an integer scanner console) to go into this method that will check which numbers are correct?
I have the following code which correctly calculates the jaccard similarity between an input char array and an existing array of char arrays. jacc_sim_rec[] is used to record the similarities which satisfy a minimum threshold value. The for loop is used to iterate through the multidimensional array and the loop is supposed to continue checking similarity if minimum threshold is not satisfied at if (jacc_sim < SIM_THRESHOLD); else record the result at
else
{
jacc_sim_rec[j] = jacc_sim;//keep record of similarity
++j;//record number of highly similar elements
}
my problem is, the whole statements in the else block is executed twice every time the threshold value is satisfied.
int j=0;
void calc_jac_sim( char*INCOMING, int grp)
{
unsigned long i, j11 = 0, j01 = 0, j10 = 0,m=0;
char *m11, *m01, *m10;
float jacc_sim = 0.0;
char r1[SBF_LEN] = { NULL };
char r2[SBF_LEN] = { NULL };
char r3[SBF_LEN] = { NULL };
int cnt = SBF_LEN - 1;
clear_jacc_sim_info();
for (int i = 0; i <= SBF_REC[grp]; ++i)
{
while (cnt >= 0)
{
r1[cnt] = SBF[grp][i][cnt] & INCOMING[cnt];
r2[cnt] = ~SBF[grp][i][cnt] & INCOMING[cnt];
r3[cnt] = SBF[grp][i][cnt] & ~INCOMING[cnt];
cnt--;
}
m11 = ( char*)r1;
m01 = ( char*)r2;
m10 = ( char*)r3;
for (m = SBF_LEN * sizeof( char); m--;
j11 += NumberOfSetBits(*m11++),
j01 += NumberOfSetBits(*m01++),
j10 += NumberOfSetBits(*m10++));
jacc_sim = j11 / (float)(j11 + j01 + j10);
if (jacc_sim < SIM_THRESHOLD);
//continue;//do nothing
else
{
jacc_sim_rec[j] = jacc_sim;//keep record of similarity
++j;//record number of highly similar elements
}
}
}
I don't understand the code, but I'll bet the problem is that you're not reinitializing cnt each time through the for loop, so you only fill in r1, r2, and r3 when i = 0.
Change that loop to:
for (int cnt = SBF_LEN - 1; cnt >= 0; cnt--)
{
r1[cnt] = SBF[grp][i][cnt] & INCOMING[cnt];
r2[cnt] = ~SBF[grp][i][cnt] & INCOMING[cnt];
r3[cnt] = SBF[grp][i][cnt] & ~INCOMING[cnt];
}
I'm also not sure why this needs to count down instead of up, like a typical loop, but it shouldn't make a difference.
Recently i have been interviewed. I didn't do well cause i got stuck at the following question
suppose a sequence is given : A D C B D A B C D A C D
and search sequence is like: A C D
task was to find the start and end index in given string that contains all the characters of search string preserving the order.
Output: assuming index start from 1:
start index 10
end index 12
explanation :
1.start/end index are not 1/3 respectively because though they contain the string but order was not maintained
2.start/end index are not 1/5 respectively because though they contain the string in the order but the length is not optimum
3.start/end index are not 6/9 respectively because though they contain the string in the order but the length is not optimum
Please go through How to find smallest substring which contains all characters from a given string?.
But the above question is different since the order is not maintained. I'm still struggling to maintain the indexes. Any help would be appreciated . thanks
I tried to write some simple c code to solve the problem:
Update:
I wrote a search function that looks for the required characters in correct order, returning the length of the window and storing the window start point to ìnt * startAt. The function processes a sub-sequence of given hay from specified startpoint int start to it's end
The rest of the algorithm is located in main where all possible subsequences are tested with a small optimisation: we start looking for the next window right after the startpoint of the previous one, so we skip some unnecessary turns. During the process we keep track f the 'till-now best solution
Complexity is O(n*n/2)
Update2:
unnecessary dependencies have been removed, unnecessary subsequent calls to strlen(...) have been replaced by size parameters passed to search(...)
#include <stdio.h>
// search for single occurrence
int search(const char hay[], int haySize, const char needle[], int needleSize, int start, int * startAt)
{
int i, charFound = 0;
// search from start to end
for (i = start; i < haySize; i++)
{
// found a character ?
if (hay[i] == needle[charFound])
{
// is it the first one?
if (charFound == 0)
*startAt = i; // store starting position
charFound++; // and go to next one
}
// are we done?
if (charFound == needleSize)
return i - *startAt + 1; // success
}
return -1; // failure
}
int main(int argc, char **argv)
{
char hay[] = "ADCBDABCDACD";
char needle[] = "ACD";
int resultStartAt, resultLength = -1, i, haySize = sizeof(hay) - 1, needleSize = sizeof(needle) - 1;
// search all possible occurrences
for (i = 0; i < haySize - needleSize; i++)
{
int startAt, length;
length = search(hay, haySize, needle, needleSize, i, &startAt);
// found something?
if (length != -1)
{
// check if it's the first result, or a one better than before
if ((resultLength == -1) || (resultLength > length))
{
resultLength = length;
resultStartAt = startAt;
}
// skip unnecessary steps in the next turn
i = startAt;
}
}
printf("start at: %d, length: %d\n", resultStartAt, resultLength);
return 0;
}
Start from the beginning of the string.
If you encounter an A, then mark the position and push it on a stack. After that, keep checking the characters sequentially until
1. If you encounter an A, update the A's position to current value.
2. If you encounter a C, push it onto the stack.
After you encounter a C, again keep checking the characters sequentially until,
1. If you encounter a D, erase the stack containing A and C and mark the score from A to D for this sub-sequence.
2. If you encounter an A, then start another Stack and mark this position as well.
2a. If now you encounter a C, then erase the earlier stacks and keep the most recent stack.
2b. If you encounter a D, then erase the older stack and mark the score and check if it is less than the current best score.
Keep doing this till you reach the end of the string.
The pseudo code can be something like:
Initialize stack = empty;
Initialize bestLength = mainString.size() + 1; // a large value for the subsequence.
Initialize currentLength = 0;
for ( int i = 0; i < mainString.size(); i++ ) {
if ( stack is empty ) {
if ( mainString[i] == 'A' ) {
start a new stack and push A on it.
mark the startPosition for this stack as i.
}
continue;
}
For each of the stacks ( there can be at most two stacks prevailing,
one of size 1 and other of size 0 ) {
if ( stack size == 1 ) // only A in it {
if ( mainString[i] == 'A' ) {
update the startPosition for this stack as i.
}
if ( mainString[i] == 'C' ) {
push C on to this stack.
}
} else if ( stack size == 2 ) // A & C in it {
if ( mainString[i] == 'C' ) {
if there is a stack with size 1, then delete this stack;// the other one dominates this stack.
}
if ( mainString[i] == 'D' ) {
mark the score from startPosition till i and update bestLength accordingly.
delete this stack.
}
}
}
}
I modified my previous suggestion using a single queue, now I believe this algorithm runs with O(N*m) time:
FindSequence(char[] sequenceList)
{
queue startSeqQueue;
int i = 0, k;
int minSequenceLength = sequenceList.length + 1;
int startIdx = -1, endIdx = -1;
for (i = 0; i < sequenceList.length - 2; i++)
{
if (sequenceList[i] == 'A')
{
startSeqQueue.queue(i);
}
}
while (startSeqQueue!=null)
{
i = startSeqQueue.enqueue();
k = i + 1;
while (sequenceList.length < k && sequenceList[k] != 'C')
if (sequenceList[i] == 'A') i = startSeqQueue.enqueue();
k++;
while (sequenceList.length < k && sequenceList[k] != 'D')
k++;
if (k < sequenceList.length && k > minSequenceLength > k - i + 1)
{
startIdx = i;
endIdx = j;
minSequenceLength = k - i + 1;
}
}
return startIdx & endIdx
}
My previous (O(1) memory) suggestion:
FindSequence(char[] sequenceList)
{
int i = 0, k;
int minSequenceLength = sequenceList.length + 1;
int startIdx = -1, endIdx = -1;
for (i = 0; i < sequenceList.length - 2; i++)
if (sequenceList[i] == 'A')
k = i+1;
while (sequenceList.length < k && sequenceList[k] != 'C')
k++;
while (sequenceList.length < k && sequenceList[k] != 'D')
k++;
if (k < sequenceList.length && k > minSequenceLength > k - i + 1)
{
startIdx = i;
endIdx = j;
minSequenceLength = k - i + 1;
}
return startIdx & endIdx;
}
Here's my version. It keeps track of possible candidates for an optimum solution. For each character in the hay, it checks whether this character is in sequence of each candidate. It then selectes the shortest candidate. Quite straightforward.
class ShortestSequenceFinder
{
public class Solution
{
public int StartIndex;
public int Length;
}
private class Candidate
{
public int StartIndex;
public int SearchIndex;
}
public Solution Execute(string hay, string needle)
{
var candidates = new List<Candidate>();
var result = new Solution() { Length = hay.Length + 1 };
for (int i = 0; i < hay.Length; i++)
{
char c = hay[i];
for (int j = candidates.Count - 1; j >= 0; j--)
{
if (c == needle[candidates[j].SearchIndex])
{
if (candidates[j].SearchIndex == needle.Length - 1)
{
int candidateLength = i - candidates[j].StartIndex;
if (candidateLength < result.Length)
{
result.Length = candidateLength;
result.StartIndex = candidates[j].StartIndex;
}
candidates.RemoveAt(j);
}
else
{
candidates[j].SearchIndex += 1;
}
}
}
if (c == needle[0])
candidates.Add(new Candidate { SearchIndex = 1, StartIndex = i });
}
return result;
}
}
It runs in O(n*m).
Here is my solution in Python. It returns the indexes assuming 0-indexed sequences. Therefore, for the given example it returns (9, 11) instead of (10, 12). Obviously it's easy to mutate this to return (10, 12) if you wish.
def solution(s, ss):
S, E = [], []
for i in xrange(len(s)):
if s[i] == ss[0]:
S.append(i)
if s[i] == ss[-1]:
E.append(i)
candidates = sorted([(start, end) for start in S for end in E
if start <= end and end - start >= len(ss) - 1],
lambda x,y: (x[1] - x[0]) - (y[1] - y[0]))
for cand in candidates:
i, j = cand[0], 0
while i <= cand[-1]:
if s[i] == ss[j]:
j += 1
i += 1
if j == len(ss):
return cand
Usage:
>>> from so import solution
>>> s = 'ADCBDABCDACD'
>>> solution(s, 'ACD')
(9, 11)
>>> solution(s, 'ADC')
(0, 2)
>>> solution(s, 'DCCD')
(1, 8)
>>> solution(s, s)
(0, 11)
>>> s = 'ABC'
>>> solution(s, 'B')
(1, 1)
>>> print solution(s, 'gibberish')
None
I think the time complexity is O(p log(p)) where p is the number of pairs of indexes in the sequence that refer to search_sequence[0] and search_sequence[-1] where the index for search_sequence[0] is less than the index forsearch_sequence[-1] because it sorts these p pairings using an O(n log n) algorithm. But then again, my substring iteration at the end could totally overshadow that sorting step. I'm not really sure.
It probably has a worst-case time complexity which is bounded by O(n*m) where n is the length of the sequence and m is the length of the search sequence, but at the moment I cannot think of an example worst-case.
Here is my O(m*n) algorithm in Java:
class ShortestWindowAlgorithm {
Multimap<Character, Integer> charToNeedleIdx; // Character -> indexes in needle, from rightmost to leftmost | Multimap is a class from Guava
int[] prefixesIdx; // prefixesIdx[i] -- rightmost index in the hay window that contains the shortest found prefix of needle[0..i]
int[] prefixesLengths; // prefixesLengths[i] -- shortest window containing needle[0..i]
public int shortestWindow(String hay, String needle) {
init(needle);
for (int i = 0; i < hay.length(); i++) {
for (int needleIdx : charToNeedleIdx.get(hay.charAt(i))) {
if (firstTimeAchievedPrefix(needleIdx) || foundShorterPrefix(needleIdx, i)) {
prefixesIdx[needleIdx] = i;
prefixesLengths[needleIdx] = getPrefixNewLength(needleIdx, i);
forgetOldPrefixes(needleIdx);
}
}
}
return prefixesLengths[prefixesLengths.length - 1];
}
private void init(String needle) {
charToNeedleIdx = ArrayListMultimap.create();
prefixesIdx = new int[needle.length()];
prefixesLengths = new int[needle.length()];
for (int i = needle.length() - 1; i >= 0; i--) {
charToNeedleIdx.put(needle.charAt(i), i);
prefixesIdx[i] = -1;
prefixesLengths[i] = -1;
}
}
private boolean firstTimeAchievedPrefix(int needleIdx) {
int shortestPrefixSoFar = prefixesLengths[needleIdx];
return shortestPrefixSoFar == -1 && (needleIdx == 0 || prefixesLengths[needleIdx - 1] != -1);
}
private boolean foundShorterPrefix(int needleIdx, int hayIdx) {
int shortestPrefixSoFar = prefixesLengths[needleIdx];
int newLength = getPrefixNewLength(needleIdx, hayIdx);
return newLength <= shortestPrefixSoFar;
}
private int getPrefixNewLength(int needleIdx, int hayIdx) {
return needleIdx == 0 ? 1 : (prefixesLengths[needleIdx - 1] + (hayIdx - prefixesIdx[needleIdx - 1]));
}
private void forgetOldPrefixes(int needleIdx) {
if (needleIdx > 0) {
prefixesLengths[needleIdx - 1] = -1;
prefixesIdx[needleIdx - 1] = -1;
}
}
}
It works on every input and also can handle repeated characters etc.
Here are some examples:
public class StackOverflow {
public static void main(String[] args) {
ShortestWindowAlgorithm algorithm = new ShortestWindowAlgorithm();
System.out.println(algorithm.shortestWindow("AXCXXCAXCXAXCXCXAXAXCXCXDXDXDXAXCXDXAXAXCD", "AACD")); // 6
System.out.println(algorithm.shortestWindow("ADCBDABCDACD", "ACD")); // 3
System.out.println(algorithm.shortestWindow("ADCBDABCD", "ACD")); // 4
}
I haven't read every answer here, but I don't think anyone has noticed that this is just a restricted version of local pairwise sequence alignment, in which we are only allowed to insert characters (and not delete or substitute them). As such it will be solved by a simplification of the Smith-Waterman algorithm that considers only 2 cases per vertex (arriving at the vertex either by matching a character exactly, or by inserting a character) rather than 3 cases. This algorithm is O(n^2).
Here's my solution. It follows one of the pattern matching solutions. Please comment/correct me if I'm wrong.
Given the input string as in the question
A D C B D A B C D A C D. Let's first compute the indices where A occurs. Assuming a zero based index this should be [0,5,9].
Now the pseudo code is as follows.
Store the indices of A in a list say *orders*.// orders=[0,5,9]
globalminStart, globalminEnd=0,localMinStart=0,localMinEnd=0;
for (index: orders)
{
int i =index;
Stack chars=new Stack();// to store the characters
i=localminStart;
while(i< length of input string)
{
if(str.charAt(i)=='C') // we've already seen A, so we look for C
st.push(str.charAt(i));
i++;
continue;
else if(str.charAt(i)=='D' and st.peek()=='C')
localminEnd=i; // we have a match! so assign value of i to len
i+=1;
break;
else if(str.charAt(i)=='A' )// seen the next A
break;
}
if (globalMinEnd-globalMinStart<localMinEnd-localMinStart)
{
globalMinEnd=localMinEnd;
globalMinStart=localMinStart;
}
}
return [globalMinstart,globalMinEnd]
}
P.S: this is pseudocode and a rough idea. Id be happy to correct it and understand if there's something wrong.
AFAIC Time complexity -O(n). Space complexity O(n)
I've written some code in C to try adn find whether or not a number is a Palindrome. The rule is that two 3 digit numbers have to be multiplied together and you have to find the highest palindrome. the answer should be 906609 but my code only gets to 580085.
the code:
#include <stdio.h>
#include <stdlib.h>
/* Intialise */
void CalcPalin();
int CheckPalin(int number);
/* Functions */
void CalcPalin()
{
int result = 0;
int palin = 0;
int FNumber = 0;
int FNumber2 = 0;
int number = 99;
int number2 = 100;
while(number2 < 1000)
{
number += 1;
/*times together - calc result*/
result = number * number2;
if(CheckPalin(result) == 1)
{
palin = result;
FNumber = number;
FNumber2 = number2;
}
if(number == 999)
{
number = 99;
number2 += 1;
}
}
printf(" Result = %d, by Multiplying [%d] and [%d]", palin, FNumber, FNumber2 );
}
int CheckPalin(int number)
{
int checknum, checknum2 = 0;
checknum = number;
while(checknum)
{
checknum2 = checknum2 * 10 + checknum % 10;
checknum /= 10;
}
if( number == checknum2)
return 1;
else
return 0;
}
int main( void)
{
CalcPalin();
return EXIT_SUCCESS;
}
Im pretty sure its a stupid answer and im over looking something simple but i cant seem to find it. Any help would be great
You have not tested whether the current result is higher than one old result. Add this check.
// test new result is higher than old palin before setting this as palin
if(CheckPalin(result) == 1 && palin < result)
Your algorithm print :
Result = 580085, by Multiplying [583] and [995]
It seems that you should find a way to increment more the 1st number. There is many possibility between 583 and 999 in order to get to 906609.
EDIT : In fact, you are looking for 993 * 913 = 906609.