Attempting a boolean in a switch with number limits of low, medium, and high - switch-statement

I'm trying to assign a percentage of a number to it's number limit it worked as an If/Else statement but when I tried to convert it to a boolean Switch I get a "not a statement" error
I cant tell what it is that I'm doing wrong here.
public static boolean taxRate(double rate)
{
final double LOW_LIM = 15000;
final double LOW_RATE = 0.25;
final double MEDIUM_LIM = 49001;
final double MEDIUM_RATE = 0.5;
final double HIGH_LIM = 49002;
final double HIGH_RATE = 0.75;
boolean taxRate;
switch(taxlimit)
{
case(LOW_LIM):
yearlyIncome <= LOW_LIM;
taxRate = LOW_RATE;
break;
case(MEDIUM_LIM):
yearlyIncome <= yearlyIncome >= MEDIUM_LIM && yearlyIncome < HIGH_LIM;
taxRate = MEDIUM_RATE;
break;
case(HIGH_LIM):
yearlyIncome <= HIGH_LIM;
taxRate = HIGH_RATE;
}
return taxRate();
}

The switch statement only works with constants and only checks for equality. You can replase IF/ELSE with a SWITCH only if your IFs look like this
if (var == const1) .....;
else if (var == const2) ....;
else if (var == const3) ....;
else .....;
This
yearlyIncome <= yearlyIncome >= MEDIUM_LIM && yearlyIncome < HIGH_LIM;
is not a statement, but an expression - it does not say WHAT to do. A statement MUST say what to do.

Related

why is my string being read this way?

I am trying to recreate atoi and I'm wondering why my function works. I ended up changing it to str[i] for the three top statements because it made sense to me, but it passed everything I threw at it.
i = 0;
result = 0;
negative = 1;
if (str[0] == '-')
{
negative = -1;
i++;
}
if (str[0] == '+')
i++;
while (str[0] <= ' ')
i++;
while (str[i] != '\0')
if (str[i] >= '0' && str[i] <= '9')
{
result = result * 10 + str[i] - '0';
++i;
}
return (result * negative);
The first if statement simply checks to see if the number should be a negative.
The second if statement checks to see if the string starts with the optional positive sign
The first while loop should run to infinity if a character who’s ascii is less than the ascii for space(32)
The second while loop simply loops through the string and converts the string to int
Changing the first 3 str[0] to str[i] shouldn’t make much of a difference since i has been initialised to 0. An exception would be if your string started with “-+” which shouldn’t be a valid integer or there’s a space between the signs and the numbers

Breakdown of Drug's Dosage weight (mg) to tablets

I am writing a piece of code in c# to retreive number of tablets for a given dosage. For example, if a Dosage is 20 mg of DrugA (if DrugA comes in 10mg, 5mg and 2mg tablets) then the code would return (2). If Dosage is 15 then the code would return (1 & 1). If a dosage is 3 then Invalid Dosage message is returned. The code must use the highest denominations first i.e. 10mg tablets and then 5mg tablets for the remainder and so on. I am using recursive function (GetDispenseBreakdownForSingleDosage) to acheive the above functionality. My code is working fine for most of the scenarios that I tested. The one scenario that it is incorrectly returning Invalid Dosage is for 8mg dosage. The code should return (4) since 2mg tablets is a valid option. I have given my code below. My questions are:
1) Is there a better way of acheiving my objective than using my code.
2) What changes should I make to avoid the trap of 8mg as invalid dosage. It is returning it invalid because code divides 8 with 5 during second recursive call and remainder becomes 3, on third recursive call 3 is not divisible by 2 so code returns invalid dosage.
My code is given below:
public string GetDispenseBreakdown(PrescriptionsBLL Prescription, double[] IndexAndNonIndexDosageForBreakdown)
{
int[] NoOfTablets = new int[Prescription.SelectedDrug.PrescriptionsDrugWeights.Count];
for (int Index = 1; Index <= IndexAndNonIndexDosageForBreakdown.Length; Index++)
{
GetDispenseBreakdownForSingleDosage(Prescription, ref NoOfTablets, IndexAndNonIndexDosageForBreakdown[(Index - 1)], Prescription.SelectedDrug.PrescriptionsDrugWeights[0].Weight, 1);//assuming that index 0 will always contain the highest weight i.e. if a drug has 2, 5, 10 as drug weights then index 0 should always contain 10 as we are sorting by Desc
}
return ConvertNumberOfTabletsIntoString(NoOfTablets);
}
public void GetDispenseBreakdownForSingleDosage(PrescriptionsBLL Prescription, ref int[] NoOfTablets, double Dosage, double Weight, int WeightCount)
{
int LoopIteration;
string TempLoopIteration = (Dosage / Weight).ToString();
if (TempLoopIteration.Contains("."))
LoopIteration = (int)Math.Floor(Dosage / Weight);
else
LoopIteration = int.Parse(TempLoopIteration);
double TempDosage = Weight * LoopIteration;
int WeightTablets = LoopIteration;
double RemainingDosage = Math.Round((Dosage - TempDosage), 2);
NoOfTablets[(WeightCount - 1)] = NoOfTablets[(WeightCount - 1)] + WeightTablets;
if (WeightCount == Prescription.SelectedDrug.PrescriptionsDrugWeights.Count && RemainingDosage > 0.0)
{
NoOfTablets[0] = -99999;//Invalid Dosage
return;
}
if (LoopIteration == 0 && Dosage > 0.0 && WeightCount == Prescription.SelectedDrug.PrescriptionsDrugWeights.Count)
{
NoOfTablets[0] = -99999;//Invalid Dosage
return;
}
if (WeightCount == Prescription.SelectedDrug.PrescriptionsDrugWeights.Count)
return;
GetDispenseBreakdownForSingleDosage(Prescription, ref NoOfTablets, RemainingDosage, Prescription.SelectedDrug.PrescriptionsDrugWeights[WeightCount].Weight, ++WeightCount);
}
public bool IsDosageValid(int[] NoOfTablets)
{
if (NoOfTablets[0] == -99999)
return false;
else
return true;
}
public string ConvertNumberOfTabletsIntoString(int[] NoOfTablets)
{
if (!IsDosageValid(NoOfTablets))
return "Dosage is Invalid";
string DispenseBreakDown = "(";
int ItemsAdded = 0;
for (int Count = 0; Count < NoOfTablets.Length; Count++)
{
if (NoOfTablets[Count] != 0)
{
if (ItemsAdded > 0)
DispenseBreakDown += " & " + NoOfTablets[Count];
else
DispenseBreakDown += NoOfTablets[Count];
ItemsAdded = ItemsAdded + 1;
}
}
DispenseBreakDown += ")";
return DispenseBreakDown;
}
This sounds like a version of the same logic required for coin change.
This site goes through that logic:
http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/
You will also need to make a few adjustments:
You'll need to get back the possible results and accept the one that has highest number of larger pills.
You'll need to handle the possibility of no "correct change".
Here is a simple recursive method. Pass it the desired dosage and an empty list:
// Test if 2 floats are "equal", the difference between them
// is less than some predefined value (epsilon)
bool floatIsEqual(float f1, float f2)
{
float epsilon = 0.001f;
return Math.Abs(f1 - f2) <= epsilon;
}
static bool CalcDose(float desired, List<float> list)
{
// Order of array is important. Larger values will be attempted first
float[] sizes = new float[] { 8, 2, .4f, .2f };
// This path isn't working, return
if (desired < sizes[sizes.Length - 1])
{
return false;
}
// Try all combos
for (int i = 0; i < sizes.Length; i++)
{
if (floatIsEqual(desired, sizes[i]))
{
// Final step: perfect match
list.Add(sizes[i]);
return true;
}
if (sizes[i] <= desired)
{
// Attempt recursive call
if (true == CalcDose( desired - sizes[i], list))
{
// Success
list.Add(sizes[i]);
return true;
}
else break;
}
}
return false;
}

Check if a string is rotation of another WITHOUT concatenating

There are 2 strings , how can we check if one is a rotated version of another ?
For Example : hello --- lohel
One simple solution is by concatenating first string with itself and checking if the other one is a substring of the concatenated version.
Is there any other solution to it ?
I was wondering if we could use circular linked list maybe ? But I am not able to arrive at the solution.
One simple solution is by concatenating them and checking if the other one is a substring of the concatenated version.
I assume you mean concatenate the first string with itself, then check if the other one is a substring of that concatenation.
That will work, and in fact can be done without any concatenation at all. Just use any string searching algorithm to search for the second string in the first, and when you reach the end, loop back to the beginning.
For instance, using Boyer-Moore the overall algorithm would be O(n).
There's no need to concatenate at all.
First, check the lengths. If they're different then return false.
Second, use an index that increments from the first character to the last of the source. Check if the destination starts with all the letters from the index to the end, and ends with all the letters before the index. If at any time this is true, return true.
Otherwise, return false.
EDIT:
An implementation in Python:
def isrot(src, dest):
# Make sure they have the same size
if len(src) != len(dest):
return False
# Rotate through the letters in src
for ix in range(len(src)):
# Compare the end of src with the beginning of dest
# and the beginning of src with the end of dest
if dest.startswith(src[ix:]) and dest.endswith(src[:ix]):
return True
return False
print isrot('hello', 'lohel')
print isrot('hello', 'lohell')
print isrot('hello', 'hello')
print isrot('hello', 'lohe')
You could compute the lexicographically minimal string rotation of each string and then test if they were equal.
Computing the minimal rotation is O(n).
This would be good if you had lots of strings to test as the minimal rotation could be applied as a preprocessing step and then you could use a standard hash table to store the rotated strings.
Trivial O(min(n,m)^2) algorithm: (n - length of S1, m - length of S2)
isRotated(S1 , S2):
if (S1.length != S2.length)
return false
for i : 0 to n-1
res = true
index = i
for j : 0 to n-1
if S1[j] != S2[index]
res = false
break
index = (index+1)%n
if res == true
return true
return false
EDIT:
Explanation -
Two strings S1 and S2 of lengths m and n respectively are cyclic identical if and only if m == n and exist index 0 <= j <= n-1 such S1 = S[j]S[j+1]...S[n-1]S[0]...S[j-1].
So in the above algorithm we check if the length is equal and if exist such an index.
A very straightforward solution is to rotate one of the words n times, where n is the length of the word. For each of those rotations, check to see if the result is the same as the other word.
You can do it in O(n) time and O(1) space:
def is_rot(u, v):
n, i, j = len(u), 0, 0
if n != len(v):
return False
while i < n and j < n:
k = 1
while k <= n and u[(i + k) % n] == v[(j + k) % n]:
k += 1
if k > n:
return True
if u[(i + k) % n] > v[(j + k) % n]:
i += k
else:
j += k
return False
See my answer here for more details.
Simple solution in Java. No need of iteration or concatenation.
private static boolean isSubString(String first, String second){
int firstIndex = second.indexOf(first.charAt(0));
if(first.length() == second.length() && firstIndex > -1){
if(first.equalsIgnoreCase(second))
return true;
int finalPos = second.length() - firstIndex ;
return second.charAt(0) == first.charAt(finalPos)
&& first.substring(finalPos).equals(second.subSequence(0, firstIndex));
}
return false;
}
Test case:
String first = "bottle";
String second = "tlebot";
Logic:
Take the first string's first character, find the index in the second string. Subtract the length of the second with the index found, check if first character of the second at 0 is same as character at the difference of length of the second and index found and substrings between those 2 characters are the same.
Another python implementation (without concatenation) although not efficient but it's O(n), looking forward for comments if any.
Assume that there are two strings s1 and s2.
Obviously, if s1 and s2 are rotations, there exists two sub strings of s2 in s1, the sum of them will total to the length of the string.
The question is to find that partition for which I increment an index in s2 whenever a char of s2 matches with that of s1.
def is_rotation(s1, s2):
if len(s1) != len(s2):
return False
n = len(s1)
if n == 0: return True
j = 0
for i in range(n):
if s2[j] == s1[i]:
j += 1
return (j > 0 and s1[:n - j] == s2[j:] and s1[n - j:] == s2[:j])
The second and condition is just to ensure that the counter incremented for s2 are a sub string match.
input1= "hello" input2="llohe" input3="lohel"(input3 is special case)
if length's of input 1 & input2 are not same return 0.Let i and j be two indexes pointing to input1 and input2 respectively and initialize count to input1.length. Have a flag called isRotated which is set to false
while(count != 0){
When the character's of input1 matches input2
increment i & j
decrement count
If the character's donot match
if isRotated = true(it means even after rotation there's mismatch) so break;
else Reset j to 0 as there's a mismatch. Eg:
Please find the code below and let me know if it fails for some other combination I may not have considered.
public boolean isRotation(String input1, String input2) {
boolean isRotated = false;
int i = 0, j = 0, count = input1.length();
if (input1.length() != input2.length())
return false;
while (count != 0) {
if (i == input1.length() && !isRotated) {
isRotated = true;
i = 0;
}
if (input1.charAt(i) == input2.charAt(j)) {
i++;
j++;
count--;
}
else {
if (isRotated) {
break;
}
if (i == input1.length() - 1 && !isRotated) {
isRotated = true;
}
if (i < input1.length()) {
j = 0;
count = input1.length();
}
/* To handle the duplicates. This is the special case.
* This occurs when input1 contains two duplicate elements placed side-by-side as "ll" in "hello" while
* they may not be side-by-side in input2 such as "lohel" but are still valid rotations.
Eg: "hello" "lohel"
*/
if (input1.charAt(i) == input2.charAt(j)) {
i--;
}
i++;
}
}
if (count == 0)
return true;
return false;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(new StringRotation().isRotation("harry potter",
"terharry pot"));
System.out.println(new StringRotation().isRotation("hello", "llohe"));
System.out.println(new StringRotation().isRotation("hello", "lohell"));
System.out.println(new StringRotation().isRotation("hello", "hello"));
System.out.println(new StringRotation().isRotation("hello", "lohe"));
}
Solving the problem in O(n)
void isSubstring(string& s1, string& s2)
{
if(s1.length() != s2.length())
cout<<"Not rotation string"<<endl;
else
{
int firstI=0, secondI=0;
int len = s1.length();
while( firstI < len )
{
if(s1[firstI%len] == s2[0] && s1[(firstI+1) %len] == s2[1])
break;
firstI = (firstI+1)%len;
}
int len2 = s2.length();
int i=0;
bool isSubString = true;
while(i < len2)
{
if(s1[firstI%len] != s2[i])
{
isSubString = false;
break;
}
i++;
}
if(isSubString)
cout<<"Is Rotation String"<<endl;
else
cout<<"Is not a rotation string"<<endl;
}
}
String source = "avaraavar";
String dest = "ravaraava";
System.out.println();
if(source.length()!=dest.length())
try {
throw (new IOException());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int i = 0;
int j = 0;
int totalcount=0;
while(true)
{
i=i%source.length();
if(source.charAt(i)==dest.charAt(j))
{
System.out.println("i="+i+" , j = "+j);
System.out.println(source.charAt(i)+"=="+dest.charAt(j));
i++;
j++;
totalcount++;
}
else
{
System.out.println("i="+i+" , j = "+j);
System.out.println(source.charAt(i)+"!="+dest.charAt(j));
i++;
totalcount++;
j=0;
}
if(j==source.length())
{
System.out.println("Yes its a rotation");
break;
}
if(totalcount >(2*source.length())-1)
{
System.out.println("No its a rotation");
break;
}
}

How to find smallest substring which contains all characters from a given string?

I have recently come across an interesting question on strings. Suppose you are given following:
Input string1: "this is a test string"
Input string2: "tist"
Output string: "t stri"
So, given above, how can I approach towards finding smallest substring of string1 that contains all the characters from string 2?
To see more details including working code, check my blog post at:
http://www.leetcode.com/2010/11/finding-minimum-window-in-s-which.html
To help illustrate this approach, I use an example: string1 = "acbbaca" and string2 = "aba". Here, we also use the term "window", which means a contiguous block of characters from string1 (could be interchanged with the term substring).
i) string1 = "acbbaca" and string2 = "aba".
ii) The first minimum window is found.
Notice that we cannot advance begin
pointer as hasFound['a'] ==
needToFind['a'] == 2. Advancing would
mean breaking the constraint.
iii) The second window is found. begin
pointer still points to the first
element 'a'. hasFound['a'] (3) is
greater than needToFind['a'] (2). We
decrement hasFound['a'] by one and
advance begin pointer to the right.
iv) We skip 'c' since it is not found
in string2. Begin pointer now points to 'b'.
hasFound['b'] (2) is greater than
needToFind['b'] (1). We decrement
hasFound['b'] by one and advance begin
pointer to the right.
v) Begin pointer now points to the
next 'b'. hasFound['b'] (1) is equal
to needToFind['b'] (1). We stop
immediately and this is our newly
found minimum window.
The idea is mainly based on the help of two pointers (begin and end position of the window) and two tables (needToFind and hasFound) while traversing string1. needToFind stores the total count of a character in string2 and hasFound stores the total count of a character met so far. We also use a count variable to store the total characters in string2 that's met so far (not counting characters where hasFound[x] exceeds needToFind[x]). When count equals string2's length, we know a valid window is found.
Each time we advance the end pointer (pointing to an element x), we increment hasFound[x] by one. We also increment count by one if hasFound[x] is less than or equal to needToFind[x]. Why? When the constraint is met (that is, count equals to string2's size), we immediately advance begin pointer as far right as possible while maintaining the constraint.
How do we check if it is maintaining the constraint? Assume that begin points to an element x, we check if hasFound[x] is greater than needToFind[x]. If it is, we can decrement hasFound[x] by one and advancing begin pointer without breaking the constraint. On the other hand, if it is not, we stop immediately as advancing begin pointer breaks the window constraint.
Finally, we check if the minimum window length is less than the current minimum. Update the current minimum if a new minimum is found.
Essentially, the algorithm finds the first window that satisfies the constraint, then continue maintaining the constraint throughout.
You can do a histogram sweep in O(N+M) time and O(1) space where N is the number of characters in the first string and M is the number of characters in the second.
It works like this:
Make a histogram of the second string's characters (key operation is hist2[ s2[i] ]++).
Make a cumulative histogram of the first string's characters until that histogram contains every character that the second string's histogram contains (which I will call "the histogram condition").
Then move forwards on the first string, subtracting from the histogram, until it fails to meet the histogram condition. Mark that bit of the first string (before the final move) as your tentative substring.
Move the front of the substring forwards again until you meet the histogram condition again. Move the end forwards until it fails again. If this is a shorter substring than the first, mark that as your tentative substring.
Repeat until you've passed through the entire first string.
The marked substring is your answer.
Note that by varying the check you use on the histogram condition, you can choose either to have the same set of characters as the second string, or at least as many characters of each type. (Its just the difference between a[i]>0 && b[i]>0 and a[i]>=b[i].)
You can speed up the histogram checks if you keep a track of which condition is not satisfied when you're trying to satisfy it, and checking only the thing that you decrement when you're trying to break it. (On the initial buildup, you count how many items you've satisfied, and increment that count every time you add a new character that takes the condition from false to true.)
Here's an O(n) solution. The basic idea is simple: for each starting index, find the least ending index such that the substring contains all of the necessary letters. The trick is that the least ending index increases over the course of the function, so with a little data structure support, we consider each character at most twice.
In Python:
from collections import defaultdict
def smallest(s1, s2):
assert s2 != ''
d = defaultdict(int)
nneg = [0] # number of negative entries in d
def incr(c):
d[c] += 1
if d[c] == 0:
nneg[0] -= 1
def decr(c):
if d[c] == 0:
nneg[0] += 1
d[c] -= 1
for c in s2:
decr(c)
minlen = len(s1) + 1
j = 0
for i in xrange(len(s1)):
while nneg[0] > 0:
if j >= len(s1):
return minlen
incr(s1[j])
j += 1
minlen = min(minlen, j - i)
decr(s1[i])
return minlen
I received the same interview question. I am a C++ candidate but I was in a position to code relatively fast in JAVA.
Java [Courtesy : Sumod Mathilakath]
import java.io.*;
import java.util.*;
class UserMainCode
{
public String GetSubString(String input1,String input2){
// Write code here...
return find(input1, input2);
}
private static boolean containsPatternChar(int[] sCount, int[] pCount) {
for(int i=0;i<256;i++) {
if(pCount[i]>sCount[i])
return false;
}
return true;
}
public static String find(String s, String p) {
if (p.length() > s.length())
return null;
int[] pCount = new int[256];
int[] sCount = new int[256];
// Time: O(p.lenght)
for(int i=0;i<p.length();i++) {
pCount[(int)(p.charAt(i))]++;
sCount[(int)(s.charAt(i))]++;
}
int i = 0, j = p.length(), min = Integer.MAX_VALUE;
String res = null;
// Time: O(s.lenght)
while (j < s.length()) {
if (containsPatternChar(sCount, pCount)) {
if ((j - i) < min) {
min = j - i;
res = s.substring(i, j);
// This is the smallest possible substring.
if(min==p.length())
break;
// Reduce the window size.
sCount[(int)(s.charAt(i))]--;
i++;
}
} else {
sCount[(int)(s.charAt(j))]++;
// Increase the window size.
j++;
}
}
System.out.println(res);
return res;
}
}
C++ [Courtesy : sundeepblue]
#include <iostream>
#include <vector>
#include <string>
#include <climits>
using namespace std;
string find_minimum_window(string s, string t) {
if(s.empty() || t.empty()) return;
int ns = s.size(), nt = t.size();
vector<int> total(256, 0);
vector<int> sofar(256, 0);
for(int i=0; i<nt; i++)
total[t[i]]++;
int L = 0, R;
int minL = 0; //gist2
int count = 0;
int min_win_len = INT_MAX;
for(R=0; R<ns; R++) { // gist0, a big for loop
if(total[s[R]] == 0) continue;
else sofar[s[R]]++;
if(sofar[s[R]] <= total[s[R]]) // gist1, <= not <
count++;
if(count == nt) { // POS1
while(true) {
char c = s[L];
if(total[c] == 0) { L++; }
else if(sofar[c] > total[c]) {
sofar[c]--;
L++;
}
else break;
}
if(R - L + 1 < min_win_len) { // this judge should be inside POS1
min_win_len = R - L + 1;
minL = L;
}
}
}
string res;
if(count == nt) // gist3, cannot forget this.
res = s.substr(minL, min_win_len); // gist4, start from "minL" not "L"
return res;
}
int main() {
string s = "abdccdedca";
cout << find_minimum_window(s, "acd");
}
Erlang [Courtesy : wardbekker]
-module(leetcode).
-export([min_window/0]).
%% Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
%% For example,
%% S = "ADOBECODEBANC"
%% T = "ABC"
%% Minimum window is "BANC".
%% Note:
%% If there is no such window in S that covers all characters in T, return the emtpy string "".
%% If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
min_window() ->
"eca" = min_window("cabeca", "cae"),
"eca" = min_window("cfabeca", "cae"),
"aec" = min_window("cabefgecdaecf", "cae"),
"cwae" = min_window("cabwefgewcwaefcf", "cae"),
"BANC" = min_window("ADOBECODEBANC", "ABC"),
ok.
min_window(T, S) ->
min_window(T, S, []).
min_window([], _T, MinWindow) ->
MinWindow;
min_window([H | Rest], T, MinWindow) ->
NewMinWindow = case lists:member(H, T) of
true ->
MinWindowFound = fullfill_window(Rest, lists:delete(H, T), [H]),
case length(MinWindow) == 0 orelse (length(MinWindow) > length(MinWindowFound)
andalso length(MinWindowFound) > 0) of
true ->
MinWindowFound;
false ->
MinWindow
end;
false ->
MinWindow
end,
min_window(Rest, T, NewMinWindow).
fullfill_window(_, [], Acc) ->
%% window completed
Acc;
fullfill_window([], _T, _Acc) ->
%% no window found
"";
fullfill_window([H | Rest], T, Acc) ->
%% completing window
case lists:member(H, T) of
true ->
fullfill_window(Rest, lists:delete(H, T), Acc ++ [H]);
false ->
fullfill_window(Rest, T, Acc ++ [H])
end.
REF:
http://articles.leetcode.com/finding-minimum-window-in-s-which/#comment-511216
http://www.mif.vu.lt/~valdas/ALGORITMAI/LITERATURA/Cormen/Cormen.pdf
Please have a look at this as well:
//-----------------------------------------------------------------------
bool IsInSet(char ch, char* cSet)
{
char* cSetptr = cSet;
int index = 0;
while (*(cSet+ index) != '\0')
{
if(ch == *(cSet+ index))
{
return true;
}
++index;
}
return false;
}
void removeChar(char ch, char* cSet)
{
bool bShift = false;
int index = 0;
while (*(cSet + index) != '\0')
{
if( (ch == *(cSet + index)) || bShift)
{
*(cSet + index) = *(cSet + index + 1);
bShift = true;
}
++index;
}
}
typedef struct subStr
{
short iStart;
short iEnd;
short szStr;
}ss;
char* subStringSmallest(char* testStr, char* cSet)
{
char* subString = NULL;
int iSzSet = strlen(cSet) + 1;
int iSzString = strlen(testStr)+ 1;
char* cSetBackUp = new char[iSzSet];
memcpy((void*)cSetBackUp, (void*)cSet, iSzSet);
int iStartIndx = -1;
int iEndIndx = -1;
int iIndexStartNext = -1;
std::vector<ss> subStrVec;
int index = 0;
while( *(testStr+index) != '\0' )
{
if (IsInSet(*(testStr+index), cSetBackUp))
{
removeChar(*(testStr+index), cSetBackUp);
if(iStartIndx < 0)
{
iStartIndx = index;
}
else if( iIndexStartNext < 0)
iIndexStartNext = index;
else
;
if (strlen(cSetBackUp) == 0 )
{
iEndIndx = index;
if( iIndexStartNext == -1)
break;
else
{
index = iIndexStartNext;
ss stemp = {iStartIndx, iEndIndx, (iEndIndx-iStartIndx + 1)};
subStrVec.push_back(stemp);
iStartIndx = iEndIndx = iIndexStartNext = -1;
memcpy((void*)cSetBackUp, (void*)cSet, iSzSet);
continue;
}
}
}
else
{
if (IsInSet(*(testStr+index), cSet))
{
if(iIndexStartNext < 0)
iIndexStartNext = index;
}
}
++index;
}
int indexSmallest = 0;
for(int indexVec = 0; indexVec < subStrVec.size(); ++indexVec)
{
if(subStrVec[indexSmallest].szStr > subStrVec[indexVec].szStr)
indexSmallest = indexVec;
}
subString = new char[(subStrVec[indexSmallest].szStr) + 1];
memcpy((void*)subString, (void*)(testStr+ subStrVec[indexSmallest].iStart), subStrVec[indexSmallest].szStr);
memset((void*)(subString + subStrVec[indexSmallest].szStr), 0, 1);
delete[] cSetBackUp;
return subString;
}
//--------------------------------------------------------------------
Edit: apparently there's an O(n) algorithm (cf. algorithmist's answer). Obviously this have this will beat the [naive] baseline described below!
Too bad I gotta go... I'm a bit suspicious that we can get O(n). I'll check in tomorrow to see the winner ;-) Have fun!
Tentative algorithm:
The general idea is to sequentially try and use a character from str2 found in str1 as the start of a search (in either/both directions) of all the other letters of str2. By keeping a "length of best match so far" value, we can abort searches when they exceed this. Other heuristics can probably be used to further abort suboptimal (so far) solutions. The choice of the order of the starting letters in str1 matters much; it is suggested to start with the letter(s) of str1 which have the lowest count and to try with the other letters, of an increasing count, in subsequent attempts.
[loose pseudo-code]
- get count for each letter/character in str1 (number of As, Bs etc.)
- get count for each letter in str2
- minLen = length(str1) + 1 (the +1 indicates you're not sure all chars of
str2 are in str1)
- Starting with the letter from string2 which is found the least in string1,
look for other letters of Str2, in either direction of str1, until you've
found them all (or not, at which case response = impossible => done!).
set x = length(corresponding substring of str1).
- if (x < minLen),
set minlen = x,
also memorize the start/len of the str1 substring.
- continue trying with other letters of str1 (going the up the frequency
list in str1), but abort search as soon as length(substring of strl)
reaches or exceed minLen.
We can find a few other heuristics that would allow aborting a
particular search, based on [pre-calculated ?] distance between a given
letter in str1 and some (all?) of the letters in str2.
- the overall search terminates when minLen = length(str2) or when
we've used all letters of str1 (which match one letter of str2)
as a starting point for the search
Here is Java implementation
public static String shortestSubstrContainingAllChars(String input, String target) {
int needToFind[] = new int[256];
int hasFound[] = new int[256];
int totalCharCount = 0;
String result = null;
char[] targetCharArray = target.toCharArray();
for (int i = 0; i < targetCharArray.length; i++) {
needToFind[targetCharArray[i]]++;
}
char[] inputCharArray = input.toCharArray();
for (int begin = 0, end = 0; end < inputCharArray.length; end++) {
if (needToFind[inputCharArray[end]] == 0) {
continue;
}
hasFound[inputCharArray[end]]++;
if (hasFound[inputCharArray[end]] <= needToFind[inputCharArray[end]]) {
totalCharCount ++;
}
if (totalCharCount == target.length()) {
while (needToFind[inputCharArray[begin]] == 0
|| hasFound[inputCharArray[begin]] > needToFind[inputCharArray[begin]]) {
if (hasFound[inputCharArray[begin]] > needToFind[inputCharArray[begin]]) {
hasFound[inputCharArray[begin]]--;
}
begin++;
}
String substring = input.substring(begin, end + 1);
if (result == null || result.length() > substring.length()) {
result = substring;
}
}
}
return result;
}
Here is the Junit Test
#Test
public void shortestSubstringContainingAllCharsTest() {
String result = StringUtil.shortestSubstrContainingAllChars("acbbaca", "aba");
assertThat(result, equalTo("baca"));
result = StringUtil.shortestSubstrContainingAllChars("acbbADOBECODEBANCaca", "ABC");
assertThat(result, equalTo("BANC"));
result = StringUtil.shortestSubstrContainingAllChars("this is a test string", "tist");
assertThat(result, equalTo("t stri"));
}
//[ShortestSubstring.java][1]
public class ShortestSubstring {
public static void main(String[] args) {
String input1 = "My name is Fran";
String input2 = "rim";
System.out.println(getShortestSubstring(input1, input2));
}
private static String getShortestSubstring(String mainString, String toBeSearched) {
int mainStringLength = mainString.length();
int toBeSearchedLength = toBeSearched.length();
if (toBeSearchedLength > mainStringLength) {
throw new IllegalArgumentException("search string cannot be larger than main string");
}
for (int j = 0; j < mainStringLength; j++) {
for (int i = 0; i <= mainStringLength - toBeSearchedLength; i++) {
String substring = mainString.substring(i, i + toBeSearchedLength);
if (checkIfMatchFound(substring, toBeSearched)) {
return substring;
}
}
toBeSearchedLength++;
}
return null;
}
private static boolean checkIfMatchFound(String substring, String toBeSearched) {
char[] charArraySubstring = substring.toCharArray();
char[] charArrayToBeSearched = toBeSearched.toCharArray();
int count = 0;
for (int i = 0; i < charArraySubstring.length; i++) {
for (int j = 0; j < charArrayToBeSearched.length; j++) {
if (String.valueOf(charArraySubstring[i]).equalsIgnoreCase(String.valueOf(charArrayToBeSearched[j]))) {
count++;
}
}
}
return count == charArrayToBeSearched.length;
}
}
This is an approach using prime numbers to avoid one loop, and replace it with multiplications. Several other minor optimizations can be made.
Assign a unique prime number to any of the characters that you want to find, and 1 to the uninteresting characters.
Find the product of a matching string by multiplying the prime number with the number of occurrences it should have. Now this product can only be found if the same prime factors are used.
Search the string from the beginning, multiplying the respective prime number as you move into a running product.
If the number is greater than the correct sum, remove the first character and divide its prime number out of your running product.
If the number is less than the correct sum, include the next character and multiply it into your running product.
If the number is the same as the correct sum you have found a match, slide beginning and end to next character and continue searching for other matches.
Decide which of the matches is the shortest.
Gist
charcount = { 'a': 3, 'b' : 1 };
str = "kjhdfsbabasdadaaaaasdkaaajbajerhhayeom"
def find (c, s):
Ns = len (s)
C = list (c.keys ())
D = list (c.values ())
# prime numbers assigned to the first 25 chars
prmsi = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89 , 97]
# primes used in the key, all other set to 1
prms = []
Cord = [ord(c) - ord('a') for c in C]
for e,p in enumerate(prmsi):
if e in Cord:
prms.append (p)
else:
prms.append (1)
# Product of match
T = 1
for c,d in zip(C,D):
p = prms[ord (c) - ord('a')]
T *= p**d
print ("T=", T)
t = 1 # product of current string
f = 0
i = 0
matches = []
mi = 0
mn = Ns
mm = 0
while i < Ns:
k = prms[ord(s[i]) - ord ('a')]
t *= k
print ("testing:", s[f:i+1])
if (t > T):
# included too many chars: move start
t /= prms[ord(s[f]) - ord('a')] # remove first char, usually division by 1
f += 1 # increment start position
t /= k # will be retested, could be replaced with bool
elif t == T:
# found match
print ("FOUND match:", s[f:i+1])
matches.append (s[f:i+1])
if (i - f) < mn:
mm = mi
mn = i - f
mi += 1
t /= prms[ord(s[f]) - ord('a')] # remove first matching char
# look for next match
i += 1
f += 1
else:
# no match yet, keep searching
i += 1
return (mm, matches)
print (find (charcount, str))
(note: this answer was originally posted to a duplicate question, the original answer is now deleted.)
C# Implementation:
public static Tuple<int, int> FindMinSubstringWindow(string input, string pattern)
{
Tuple<int, int> windowCoords = new Tuple<int, int>(0, input.Length - 1);
int[] patternHist = new int[256];
for (int i = 0; i < pattern.Length; i++)
{
patternHist[pattern[i]]++;
}
int[] inputHist = new int[256];
int minWindowLength = int.MaxValue;
int count = 0;
for (int begin = 0, end = 0; end < input.Length; end++)
{
// Skip what's not in pattern.
if (patternHist[input[end]] == 0)
{
continue;
}
inputHist[input[end]]++;
// Count letters that are in pattern.
if (inputHist[input[end]] <= patternHist[input[end]])
{
count++;
}
// Window found.
if (count == pattern.Length)
{
// Remove extra instances of letters from pattern
// or just letters that aren't part of the pattern
// from the beginning.
while (patternHist[input[begin]] == 0 ||
inputHist[input[begin]] > patternHist[input[begin]])
{
if (inputHist[input[begin]] > patternHist[input[begin]])
{
inputHist[input[begin]]--;
}
begin++;
}
// Current window found.
int windowLength = end - begin + 1;
if (windowLength < minWindowLength)
{
windowCoords = new Tuple<int, int>(begin, end);
minWindowLength = windowLength;
}
}
}
if (count == pattern.Length)
{
return windowCoords;
}
return null;
}
I've implemented it using Python3 at O(N) efficiency:
def get(s, alphabet="abc"):
seen = {}
for c in alphabet:
seen[c] = 0
seen[s[0]] = 1
start = 0
end = 0
shortest_s = 0
shortest_e = 99999
while end + 1 < len(s):
while seen[s[start]] > 1:
seen[s[start]] -= 1
start += 1
# Constant time check:
if sum(seen.values()) == len(alphabet) and all(v == 1 for v in seen.values()) and \
shortest_e - shortest_s > end - start:
shortest_s = start
shortest_e = end
end += 1
seen[s[end]] += 1
return s[shortest_s: shortest_e + 1]
print(get("abbcac")) # Expected to return "bca"
String s = "xyyzyzyx";
String s1 = "xyz";
String finalString ="";
Map<Character,Integer> hm = new HashMap<>();
if(s1!=null && s!=null && s.length()>s1.length()){
for(int i =0;i<s1.length();i++){
if(hm.get(s1.charAt(i))!=null){
int k = hm.get(s1.charAt(i))+1;
hm.put(s1.charAt(i), k);
}else
hm.put(s1.charAt(i), 1);
}
Map<Character,Integer> t = new HashMap<>();
int start =-1;
for(int j=0;j<s.length();j++){
if(hm.get(s.charAt(j))!=null){
if(t.get(s.charAt(j))!=null){
if(t.get(s.charAt(j))!=hm.get(s.charAt(j))){
int k = t.get(s.charAt(j))+1;
t.put(s.charAt(j), k);
}
}else{
t.put(s.charAt(j), 1);
if(start==-1){
if(j+s1.length()>s.length()){
break;
}
start = j;
}
}
if(hm.equals(t)){
t = new HashMap<>();
if(finalString.length()<s.substring(start,j+1).length());
{
finalString=s.substring(start,j+1);
}
j=start;
start=-1;
}
}
}
JavaScript solution in bruteforce way:
function shortestSubStringOfUniqueChars(s){
var uniqueArr = [];
for(let i=0; i<s.length; i++){
if(uniqueArr.indexOf(s.charAt(i)) <0){
uniqueArr.push(s.charAt(i));
}
}
let windoww = uniqueArr.length;
while(windoww < s.length){
for(let i=0; i<s.length - windoww; i++){
let match = true;
let tempArr = [];
for(let j=0; j<uniqueArr.length; j++){
if(uniqueArr.indexOf(s.charAt(i+j))<0){
match = false;
break;
}
}
let checkStr
if(match){
checkStr = s.substr(i, windoww);
for(let j=0; j<uniqueArr.length; j++){
if(uniqueArr.indexOf(checkStr.charAt(j))<0){
match = false;
break;
}
}
}
if(match){
return checkStr;
}
}
windoww = windoww + 1;
}
}
console.log(shortestSubStringOfUniqueChars("ABA"));
# Python implementation
s = input('Enter the string : ')
s1 = input('Enter the substring to search : ')
l = [] # List to record all the matching combinations
check = all([char in s for char in s1])
if check == True:
for i in range(len(s1),len(s)+1) :
for j in range(0,i+len(s1)+2):
if (i+j) < len(s)+1:
cnt = 0
b = all([char in s[j:i+j] for char in s1])
if (b == True) :
l.append(s[j:i+j])
print('The smallest substring containing',s1,'is',l[0])
else:
print('Please enter a valid substring')
Java code for the approach discussed above:
private static Map<Character, Integer> frequency;
private static Set<Character> charsCovered;
private static Map<Character, Integer> encountered;
/**
* To set the first match index as an intial start point
*/
private static boolean hasStarted = false;
private static int currentStartIndex = 0;
private static int finalStartIndex = 0;
private static int finalEndIndex = 0;
private static int minLen = Integer.MAX_VALUE;
private static int currentLen = 0;
/**
* Whether we have already found the match and now looking for other
* alternatives.
*/
private static boolean isFound = false;
private static char currentChar;
public static String findSmallestSubStringWithAllChars(String big, String small) {
if (null == big || null == small || big.isEmpty() || small.isEmpty()) {
return null;
}
frequency = new HashMap<Character, Integer>();
instantiateFrequencyMap(small);
charsCovered = new HashSet<Character>();
int charsToBeCovered = frequency.size();
encountered = new HashMap<Character, Integer>();
for (int i = 0; i < big.length(); i++) {
currentChar = big.charAt(i);
if (frequency.containsKey(currentChar) && !isFound) {
if (!hasStarted && !isFound) {
hasStarted = true;
currentStartIndex = i;
}
updateEncounteredMapAndCharsCoveredSet(currentChar);
if (charsCovered.size() == charsToBeCovered) {
currentLen = i - currentStartIndex;
isFound = true;
updateMinLength(i);
}
} else if (frequency.containsKey(currentChar) && isFound) {
updateEncounteredMapAndCharsCoveredSet(currentChar);
if (currentChar == big.charAt(currentStartIndex)) {
encountered.put(currentChar, encountered.get(currentChar) - 1);
currentStartIndex++;
while (currentStartIndex < i) {
if (encountered.containsKey(big.charAt(currentStartIndex))
&& encountered.get(big.charAt(currentStartIndex)) > frequency.get(big
.charAt(currentStartIndex))) {
encountered.put(big.charAt(currentStartIndex),
encountered.get(big.charAt(currentStartIndex)) - 1);
} else if (encountered.containsKey(big.charAt(currentStartIndex))) {
break;
}
currentStartIndex++;
}
}
currentLen = i - currentStartIndex;
updateMinLength(i);
}
}
System.out.println("start: " + finalStartIndex + " finalEnd : " + finalEndIndex);
return big.substring(finalStartIndex, finalEndIndex + 1);
}
private static void updateMinLength(int index) {
if (minLen > currentLen) {
minLen = currentLen;
finalStartIndex = currentStartIndex;
finalEndIndex = index;
}
}
private static void updateEncounteredMapAndCharsCoveredSet(Character currentChar) {
if (encountered.containsKey(currentChar)) {
encountered.put(currentChar, encountered.get(currentChar) + 1);
} else {
encountered.put(currentChar, 1);
}
if (encountered.get(currentChar) >= frequency.get(currentChar)) {
charsCovered.add(currentChar);
}
}
private static void instantiateFrequencyMap(String str) {
for (char c : str.toCharArray()) {
if (frequency.containsKey(c)) {
frequency.put(c, frequency.get(c) + 1);
} else {
frequency.put(c, 1);
}
}
}
public static void main(String[] args) {
String big = "this is a test string";
String small = "tist";
System.out.println("len: " + big.length());
System.out.println(findSmallestSubStringWithAllChars(big, small));
}
def minimum_window(s, t, min_length = 100000):
d = {}
for x in t:
if x in d:
d[x]+= 1
else:
d[x] = 1
tot = sum([y for x,y in d.iteritems()])
l = []
ind = 0
for i,x in enumerate(s):
if ind == 1:
l = l + [x]
if x in d:
tot-=1
if not l:
ind = 1
l = [x]
if tot == 0:
if len(l)<min_length:
min_length = len(l)
min_length = minimum_window(s[i+1:], t, min_length)
return min_length
l_s = "ADOBECODEBANC"
t_s = "ABC"
min_length = minimum_window(l_s, t_s)
if min_length == 100000:
print "Not found"
else:
print min_length

Conways's Game of life array problems

I'm writing a Conway's life game for school. In the program I am having trouble with the arrays taking the values I am assigning them. At one point in the program they print out the value assigned to them (1) yet at the end of the program when I need to print the array to show the iterations of the game it shows an incredibly low number. The other trouble was I was encountering difficulties when putting in a loop that would ask if it wants you to run another iteration. So I removed it until the previous errors were fixed.
Im writing this with C++
#include <stdio.h>
int main (void)
{
int currentarray [12][12];
int futurearray [12][12];
char c;
char check = 'y';
int neighbors = 0;
int x = 0; // row
int y = 0; //column
printf("Birth an organism will be born in each empty location that has exactly three neighbors.\n");
printf("Death an organism with four or more organisms as neighbors will die from overcrowding.\n");
printf("An organism with fewer than two neighbors will die from loneliness.\n");
printf("Survival an organism with two or three neighbors will survive to the next generation.\n");
printf( "To create life input x, y coordinates.\n");
while ( check == 'y' )
{
printf("Enter x coordinate.\n");
scanf("%d", &x ); while((c = getchar()) != '\n' && c != EOF);
printf("Enter y coordinate.\n");
scanf("%d", &y ); while((c = getchar()) != '\n' && c != EOF);
currentarray [x][y] = 1;
printf ("%d\n", currentarray[x][y]);
printf( "Do you wish to enter more input? y/n.\n");
scanf("%c", &check); while((c = getchar()) != '\n' && c != EOF);
}
// Note - Need to add a printf statement showing the array before changes are made after input added.
// check for neighbors
while(check == 'y')
{
for(y = 0; y <= 12; y++)
{
for(x = 0; x <= 12; x++)
{
//Begin counting number of neighbors:
if(currentarray[x-1][y-1] == 1) neighbors += 1;
if(currentarray[x-1][y] == 1) neighbors += 1;
if(currentarray[x-1][y+1] == 1) neighbors += 1;
if(currentarray[x][y-1] == 1) neighbors += 1;
if(currentarray[x][y+1] == 1) neighbors += 1;
if(currentarray[x+1][y-1] == 1) neighbors += 1;
if(currentarray[x+1][y] == 1) neighbors += 1;
if(currentarray[x+1][y+1] == 1) neighbors += 1;
//Apply rules to the cell:
if(currentarray[x][y] == 1 && neighbors < 2)
futurearray[x][y] = 0;
else if(currentarray[x][y] == 1 && neighbors > 3)
futurearray[x][y] = 0;
else if(currentarray[x][y] == 1 && (neighbors == 2 || neighbors == 3))
futurearray[x][y] = 1;
else if(currentarray[x][y] == 0 && neighbors == 3)
futurearray[x][y] = 1;
}
}
}
// Set the current array to the future and change the future to 0
{
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//Begin the process
currentarray [x][y] = futurearray [x][y];
futurearray [x][y] = 0;
}
}
}
{
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//print the current life board
printf("%d ", currentarray[x][y]);
}
}
}
// Have gone through one iteration of Life
//Ask to do another iteration
printf("Do you wish to continue y/n?\n");
scanf("%c", &check); while((c = getchar()) != '\n' && c != EOF);
return 0;
}
You are defining your arrays as [12][12].
In your generation loop you walk from i = 0 to i <= 12, which is 13 steps instead of the 12 of the array. Additionally you are trying to access x-1 and y-1, which can be as low as -1. Again not inside your array.
Sometimes you get semi-useful values from within your array, but on some borders you are just accessing random data.
Try to correct your border.
You forgot to set neighbors to 0 before counting them.
Since this is C++ (not C), you might as well declare neighbors inside the loop body. Makes these kinds of issues easier to spot, too.
Also, is it me, or is that while loop never going to finish? Your braces are a mess, in general, as is your indentation. You could do yourself and us a favour by cleaning those up.
Obviously agree with all the above suggestions. One nice trick you might want to implement with Life is to create an extra border around your area. So if the user wants a 12x12 grid (and you should allow width/height to be specified and allocate memory dynamically) internally you hold a 14x14 grid corresponding to a border around the actual grid. Before running the calculation copy the top row to the bottom border, bottom row to the top border etc. Now you can run the main algorithm on the inner 12x12 grid without worrying about edge cases. This will enable your patterns to re-appear on the other side if they fall off the edge.
You're also forgetting to set the values of both arrays to zero. This will take care of the ridiculous number issue you're having. you can do that by copying this for loop:
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//Begin the process
currentarray [x][y] = futurearray [x][y];
futurearray [x][y] = 0;
}
}
and pasting it before the while loop but instead of setting currentarray[x][y] = futurearray[x][y], set it to 0. Also, if the coordinates are viewable locations instead of array co-ordinates, you'll want to change this:
printf ("%d\n", currentarray[x][y]);
to this:
printf ("%d\n", currentarray[x-1][y-1]);
I would also recommend putting a printf with a newline (\n) after each row has been printed and a tab (\t) after each item so that the formatting looks cleaner.

Resources