How do I compare string in Ocaml - string

How do I go about comparing strings? For example
"a" and "b", since "a" comes before "b" then I would put in a tuple like this("a","b"). For "c" and "b", it would be like this ("b","c")

You can compare strings with the usal comparison operators: =, <>, <, <=, >, >=.
You can also use the compare function, which returns -1 if the first string is less than the second, 1 if the first string is greater than the second, and 0 if they are equal.
# "a" < "b";;
- : bool = true
# "a" > "b";;
- : bool = false
# compare "a" "b";;
- : int = -1

Related

Python Logic Operators Binary

I am totally new to programming.
How do I write a Python script to do the following without using bitwise operators, only allow to use logical and or operators. Thanks in advance!
I'm stuck.
& and
Sets result bit to 1 if both corresponding bits are 1.
E.g. 1010 & 1100 is 1000
| or
Sets result bit to 1 if one of the two corresponding bits is 1.
E.g 1010 | 1100 is 1110
^ xor
Sets result bit to 1 only if one of the corresponding bits is 1.
E.g. 1010 ^ 1100 is 0110
Output:
Enter binary expression: 110110 & 110011
Result: 110010
expr = input('Enter binary expression: ')
n1, op, n2 = expr.split()
n1 = int(n1)
n2 = int(n2)
enter image description here
If you're not allowed to use the bitwise operators, then probably the most straightforward way would be to go bit by bit and do the comparison yourself. This is easiest to do if we represent them as strings
We don't even need to convert the inputs to integers (which can be done by calling int(n1, 2) to specify base-2 instead of base-10), since they're given as strings in binary already. If they were given in base-10, we could read them in as integers and then use the built-in bin() method to represent them as binary strings.
Since there's a method bin() that can represent an integer as a binary string (prefaced with the characters 0b, which we can remove by slicing them off), we can use that, compare digits in the string, then convert the result back into an integer.
expr = input('Enter binary expression: ') # sample: enter "110110 & 110011"
n1, op, n2 = expr.split()
# -------------
result = ''
for (c1, c2) in zip(n1, n2):
next_bit = ""
if op == "&":
next_bit = "1" if (c1 == "1" and c2 == "1") else "0"
elif op == "|":
next_bit = "1" if (c1 == "1" or c2 == "1") else "0"
elif op == "^":
next_bit = "1" if (c1 != c2) else "0"
result += next_bit
print(result)
# 110010
This isn't the most efficient way (you can do some complicated iterative arithmetic and treat the numbers as integers, instead of treating them as strings and just comparing digit by digit), but it's probably the most straightforward and easiest to understand, especially given how the numbers are inputted here.

Minimum manipulations to type the string

You have given a string called T, and you have to type it in the minimum manipulations.
There are 3 manipulations:
Insert one character to the end of the string (we called S)
Copy a substring in string S, the copied string will be stored in a clipboard
and if you copy another substring, this substring will be delete of the clipboard
Paste the copied-substring to the end of S
Example 1:
T=abcabab
We can use 6 manipulations:
Insert 'a' (S="a")
Insert 'b' (S="ab")
Insert 'c' (S="abc")
Copy "ab" into clipboard (S="abc"; clipboard: "ab")
Paste "ab" (S="abcab")
Paste "ab" (S="abcabab")
Example 2:
T = aaaaaaaaaaa
We can use 7 manipulations:
Insert 'a' (S="a")
Insert 'a' (S="aa")
Insert 'a' (S="aaa")
Copy "aaa" into clipboard (S="aaa"; clipboard: "aaa")
Paste "aaa" (S="aaaaaa")
Copy "aaaaa" into clipboard (S="aaaaaa"; clipboard: "aaaaa")
Paste "aaaaa" (S="aaaaaaaaaaa")
Solution Approach
For using the operation copy & paste, we need to keep track of every substring that can be made from the string we've built so far (string S). In c++ we can use map, unordered_map or use hash or trie, anything else.
We'll perform copy & paste only if we can paste a string whose length is greater than 1. Cause, if it's length is 1, then it'll take same
number of manupulation just to insert at the end.
Consider your first example. T=abcabab
Let's break it down.
At first, result string S is empty. So we've only one option here.
Insert character 'a' at the end of S. Increase manipulations count by 1.
Now S = "a", remaining target string "bcabab", Saved substring:
Insert character 'b' at the end of S. Increase manipulations count by 1.
Now S = "ab", remaining target string "cabab", Saved substring: "ab"
Our substring list is not empty now. So we'll try to make substring from our >remaining target string and check if that exists in our substring list.
remaining target string "cabab", Saved substring: "ab"
So we'll first check if "ca" exists in our substring list. (not
considering single character, cause we can just insert it) "ca"
doesn't exist in the list, so we'll insert character 'c' at the end of S.
Increase manipulations count by 1.
Now S = "abc", remaining target string "abab", Saved substring: "ab", "bc, "abc"
remaining target string "abab", Saved substring: "ab", "bc, "abc"
first check if "ab" exists in our substring list. It does. Now check if "aba" exists. It does not.
So we'll save the string "ab" in a string variable (let's call it
lastCopiedString), then insert "ab" at the end of S.
Increase manipulations count by 2.
Now S = "abcab", remaining target string "ab". Saved substring: "ab", "bc", "ca", "abc", "bca", "cab", "abca", "bcab", "abcab". lastCopiedString = "ab"
remaining target string "ab", Saved substring: "ab", "bc", "ca", "abc", "bca", "cab", "abca", "bcab", "abcab". lastCopiedString = "ab"
first check if "ab" exists in our substring list. It does. There's no
letter left in target string. So check if the lastCopiedString is same as
"ab". It's same in this case.
Increase manipulations count by 1.
Now S = "abcabab", remaining target string "".
Saved substring: "ab", "bc", "ca", "abc", "bca", "cab", "aba", "bab", "abca", "bcab", "caba", "abab", "abcab", "cabab", "bcabab", "abcaba", "abcabab" lastCopiedString = "ab"
We've our result , which is 6.
Your question is not clear here. From comment section, i understood you need to output the number of min manipulations require to change S to T .
Also you haven't mentioned any constraints, max time complexity.
Please try editing the post, and mention as much detail as you can. So that anyone sees your post, understands it.
I tried to share a generalized idea from what I've understood.
We can have an O(n^2 * log n) dynamic program state of dp[i][sub] where i is the current index and sub is which substring was used to create the suffix of the prefix ending at the ith index.
dp_0 = 1 // A constant
dp[i][sub] = min(
// Insert one character
1 + dp[i-1][best], // best is the min for dp[i-1]
// Only pasting
1 + dp[j-1][sub]
if exists sub T[j..i] in dp[j-1]
// Copy and paste
2 + dp[j-1][best]
if we've seen T[j..i] before j;
which we can check in log n time
by storing an ordered list of
indexes where each substring
we've seen appears, hashed by
the substring.
)
for j from i-1 down to 1
Python code:
import bisect
# Assumes the string does
# not contain the substring,
# "best" :)
def f(T):
seen = {}
dp = [{"best": float('inf')} for _ in range(len(T) + 1)]
dp[0]["best"] = 1
for i in range(1, len(T)):
sub = T[i]
# Insert one character
dp[i]["best"] = min(dp[i]["best"], 1 + dp[i-1]["best"])
for j in range(i-1, 0, -1):
sub = T[j] + sub
if sub in seen:
seen[sub].append(i)
else:
seen[sub] = [i]
# Copy and paste
end_of_sub_in_T_before_j = float('inf')
insertion_pt = bisect.bisect_left(seen[sub], j)
if insertion_pt - 1 >= 0:
end_of_sub_in_T_before_j = seen[sub][insertion_pt - 1]
if end_of_sub_in_T_before_j < j:
dp[i][sub] = 2 + dp[j-1]["best"]
# Paste only
if sub in dp[j-1]:
dp[i][sub] = min(dp[i][sub], 1 + dp[j-1][sub])
# Best for dp[i]
dp[i]["best"] = min(dp[i]["best"], dp[i][sub] if sub in dp[i] else float('inf'))
seen[T[0] + sub] = [i]
return dp[len(T)-1]["best"]
strs = [
"abcabab",
"aaaaaaaaaaa"
]
for T in strs:
print(T)
print(f(T))
print("")

Strings in mathematical operation in python

I was having some problems with my code , a statement was giving true when it should've been false
For some reason '6' > '14' was true. I changed them into int s instead of str s and the problem was solved but i was wondering why this has happened in the first place
here's a picture !(http://prntscr.com/o1c7na)!
For comparing strings it compares char by char, the first char '6' has a greater ASCII representation that '1' hence it is bigger.
Here some examples of the behaviour:
>>> "a" > "b"
False
>>> "a" > "aaa"
False
>>> "1" > "2"
False
>>> "12" > "1"
True
>>> "6" > "14"
True
>>> "6" > "1"
True
The ASCII code can be retrieve with ord:
>>> ord("6")
54
>>> ord("1")
49
This happens because the ascii string comparison happens with ascii code comparison of each letter one by one. So in the 1st step 6 is compared to 1 and since 6 is > 1 it returns true.

How do I get from string "3+10" to strings "3" "+" "10"?

I'm making a graphing calculator in Unity and I have input with strings like "3+10" and I want to split it to "3","+" and "10".
I can figure out a way to deal with them once I've got them to this form, but I really need a way to split the string to the left and right of key characters such as plus, times, exponent, etc.
I'm doing this in Unity, but a way to do this in any language should help.
C#
The following code will do what you asked for (and nothing more).
string input = "3+10-5";
string pattern = #"([-+^*\/])";
string[] substrings = Regex.Split(input, pattern);
// results in substrings = {"3", "+", "10", "-", "5"}
By using Regex.Split instead of String.Split you are able to retrieve the math operators as well. This is done by putting the math operators in a capture group ( ). If you're not familiar with regular expressions you should google the basics.
The code above will stubbornly use the math operators to split your string. If the string doesn't make sense, the method doesn't care and may even produce unexpected results. For example "5//10-" will result in {"5", "/", "", "10", "-", ""}. Note that only one / is returned and empty strings are added.
You can use more complex regular expressions to check if your string is a valid mathematical expression before you try to split it. For example ^(\d+(?:.\d+)?+([-+*^\/]\g<1>)?)$ would check if your string consists of a decimal number and zero or more combinations of an operator and another decimal number.
Here is the C# way -- which I mention because you are using Unity.
words = phrase.Split(default(string[]),StringSplitOptions.RemoveEmptyEntries);
https://msdn.microsoft.com/en-us/library/tabh47cf%28v=vs.110%29.aspx
Here is Java code for splitting a String by math operators
String[] splitByOperators(String input) {
String[] output = new String[input.length()];
int index = 0;
String current = "";
for (char c : input){
if (c == '+' || c == '-' || c == '*' || c == '/'){
output[index] = current;
index++;
output[index] = c;
index++;
current = "";
} else {
current = current + c;
}
}
output[index] = current;
return output;
}
Using Python regular expressions:
>>> import re
>>> match = re.search(r'(\d+)(.*)(\d+)', "3+1")
>>> match.group(1)
'3'
>>> match.group(2)
'+'
>>> match.group(3)
'1'
The reason for using regular expressions is for greater flexibility in handling a variety of simple arithmetic expressions.
R: EDITED
Take your input vector as x<-c("3+10", "4/12" , "8-3" ,"12*1","1+2-3*4/8").
We can use the following string split based on regex:
> strsplit(x,split="(?<=\\d)(?=[+*-/])|(?<=[+*-/])(?=\\d)",perl=T)
[[1]]
[1] "3" "+" "10"
[[2]]
[1] "4" "/" "12"
[[3]]
[1] "8" "-" "3"
[[4]]
[1] "12" "*" "1"
[[5]]
[1] "1" "+" "2" "-" "3" "*" "4" "/" "8"
How it works:
Split the string when one of two things is found:
A digit followed by an arithmetic operator. (?<=\\d) finds something immediately preceded by a digit, while (?=[+*-/]) finds something immediately succeeded by an arithmetic operator, i.e. +, *, -, or /. The "something" in both cases is the blank string "" found between a digit and an operator, and the string is split at such a point.
An arithmetic operator followed by a digit. This is just the reverse of the above.

Matlab. Find the indices of a cell array of strings with characters all contained in a given string (without repetition)

I have one string and a cell array of strings.
str = 'actaz';
dic = {'aaccttzz', 'ac', 'zt', 'ctu', 'bdu', 'zac', 'zaz', 'aac'};
I want to obtain:
idx = [2, 3, 6, 8];
I have written a very long code that:
finds the elements with length not greater than length(str);
removes the elements with characters not included in str;
finally, for each remaining element, checks the characters one by one
Essentially, it's an almost brute force code and runs very slowly. I wonder if there is a simple way to do it fast.
NB: I have just edited the question to make clear that characters can be repeated n times if they appear n times in str. Thanks Shai for pointing it out.
You can sort the strings and then match them using regular expression. For your example the pattern will be ^a{0,2}c{0,1}t{0,1}z{0,1}$:
u = unique(str);
t = ['^' sprintf('%c{0,%d}', [u; histc(str,u)]) '$'];
s = cellfun(#sort, dic, 'uni', 0);
idx = find(~cellfun('isempty', regexp(s, t)));
I came up with this :
>> g=#(x,y) sum(x==y) <= sum(str==y);
>> h=#(t)sum(arrayfun(#(x)g(t,x),t))==length(t);
>> f=cellfun(#(x)h(x),dic);
>> find(f)
ans =
2 3 6
g & h: check if number of count of each letter in search string <= number of count in str.
f : finally use g and h for each element in dic

Resources