''Given two string s and t, write a function to check if s contains all characters of t (in the same order as they are in string t).
Return true or false.
recursion not necessary.
here is the snippet of code that I am writing in java.
problem is for input: string1="st3h5irteuyarh!"
and string2="shrey"
it should return TRUE but it is returning FALSE. Why is that?''
public class Solution {
public static String getString(char x)
{
String s = String.valueOf(x);
return s;
}
public static boolean checkSequence(String s1, String s2)
{
String a = getString(s1.charAt(0));
String b = getString(s2.charAt(0));
for (int i = 1; i < s1.length(); i++)
if (s1.charAt(i) != s1.charAt(i - 1))
{
a += getString(s1.charAt(i));
}
for (int i = 1; i < s2.length(); i++)
if (s2.charAt(i) != s2.charAt(i - 1))
{
b += getString(s2.charAt(i));
}
if (!a.equals(b))
return false;
return true;
}
}
This is a solution:
public class Solution {
public static String getString(char x)
{
String s = String.valueOf(x);
return s;
}
public static boolean checkSequence(String s1, String s2)
{
String a = getString(s1.charAt(0));
String b = getString(s2.charAt(0));
int count = 0;
for (int i = 0; i < s1.length(); i++)
{
if (s1.charAt(i) == s2.charAt(count))
{
count++;
}
if (count == s2.length())
return true;
}
return false;
}
}
Each char of String s1 is compared with a char of String s2 at position count,
if they match count increases: count++;
If count has the length of String 2 all chars matched and true is returned.
there are two problems i can see in that code
1 for (int i = 1; i < s1.length(); i++) you are starting from index 1 but string indexes starts from 0
2 if (s1.charAt(i) != s1.charAt(i - 1)) here you are comparing characters of same strings s1 in other loop also this is the case
please fix these first, then ask again
this could be what you are searching for
public class Solution {
public static boolean checkSequence(String s1, String s2) {
for(char c : s2.toCharArray()) {
if(!s1.contains(c+"")) {
return false;
}
int pos = s1.indexOf(c);
s1 = s1.substring(pos);
}
return true;
}
}
Your approach to solve this problem can be something like this :
Find the smaller string.
Initialise the pointer to starting position of smaller string.
Iterate over the larger string in for loop and keep checking if character is matching.
On match increase the counter of smaller pointer.
while iterating keep checking if smaller pointer has reached to end or not. If yes then return true.
Something like this :
public static boolean checkSequence(String s1, String s2)
{
String smallerString = s1.length()<=s2.length() ? s1 : s2;
String largerString = smallerString.equals(s2) ? s1 : s2;
int smallerStringPointer=0;
for(int i=0;i<largerString.length();i++){
if(smallerString.charAt(smallerStringPointer) == largerString.charAt(i)){
smallerStringPointer++;
}
if(smallerStringPointer == smallerString.length()){
return true;
}
}
return false;
}
public static boolean usingLoops(String str1, String str2) {
int index = -10;
int flag = 0;
for (int i = 0; i < str1.length(); i++) {
flag = 0;
for (int j = i; j < str2.length(); j++) {
if (str1.charAt(i) == str2.charAt(j)) {
if (j < index) {
return false;
}
index = j;
flag = 1;
break;
}
}
if (flag == 0)
return false;
}
return true;
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String str1 = s.nextLine();
String str2 = s.nextLine();
// using loop to solve the problem
System.out.println(usingLoops(str1, str2));
s.close();
}
Related
I solved a task concerning finding the first non-repeating character. For example, given the input "apple" the answer would be "a", the first character that isn't repeated. Even though "e" is not repeated it's not the first character. Another example: "lalas" answer is "s".
public static char firstNonRepeatingCharacter(String input) {
boolean unique;
int count = input.length();
char[] chars = input.toCharArray();
for (int i = 0; i < input.length(); i++) {
unique = true;
for (int j = 0; j < input.length(); j++) {
count--;
char c = chars[i];
if (i != j && c == chars[j]) {
unique = false;
break;
}
}
if (unique) {
return input.charAt(i);
}
}
return (0);
}
I want to simplify this code due to the nested loop having O(n2) complexity. I have been looking at the code trying to figure out if i could make it any faster but nothing comes to mind.
Another way is to find the first and last indexOf the character. If both are same then it is unique.
public static char firstNonRepeatingCharacter(String input) {
for(char c:input.toCharArray())
if(input.indexOf(c) == input.lastIndexOf(c))
return c;
return (0);
}
EDIT:
Or with Java 8+
return (char) input.chars()
.filter(c -> input.indexOf(c) == input.lastIndexOf(c))
.findFirst().orElse(0);
O(n) is better.
Use an intermedian structure to handle the number of repetitions.
public static char firstNonRepeatingCharacter(String input) {
boolean unique;
int count = input.length();
char[] chars = input.toCharArray();
for (int i = 0; i < input.length(); i++) {
unique = true;
for (int j = 0; j < input.length(); j++) {
count--;
char c = chars[i];
if (i != j && c == chars[j]) {
unique = false;
break;
}
}
if (unique) {
return input.charAt(i);
}
}
return (0);
}
public static char firstNonRepeatingCharacterMyVersion(String input) {
Map<String,Integer> map = new HashMap();
// first iteration put in a map the number of times a char appears. Linear O(n)=n
for (char c : input.toCharArray()) {
String character = String.valueOf(c);
if(map.containsKey(character)){
map.put(character,map.get(character) + 1);
} else {
map.put(character,1);
}
}
// Second iteration look for first element with one element.
for (char c : input.toCharArray()) {
String character = String.valueOf(c);
if(map.get(character) == 1){
return c;
}
}
return (0);
}
public static void main(String... args){
System.out.println(firstNonRepeatingCharacter("potatoaonionp"));
System.out.println(firstNonRepeatingCharacterMyVersion("potatoaonionp"));
}
See this solution. Similar to the above #Lucbel. Basically, using a LinkedList. We store all non repeating. However, we will use more space. But running time is O(n).
import java.util.LinkedList;
import java.util.List;
public class FirstNone {
public static void main(String[] args) {
System.out.println(firstNonRepeatingCharacter("apple"));
System.out.println(firstNonRepeatingCharacter("potatoaonionp"));
System.out.println(firstNonRepeatingCharacter("tksilicon"));
}
public static char firstNonRepeatingCharacter(String input) {
List<Character> charsInput = new LinkedList<>();
char[] chars = input.toCharArray();
for (int i = 0; i < input.length(); i++) {
if (charsInput.size() == 0) {
charsInput.add(chars[i]);
} else {
if (!charsInput.contains(chars[i])) {
charsInput.add(chars[i]);
} else if (charsInput.contains(chars[i])) {
charsInput.remove(Character.valueOf(chars[i]));
}
}
}
if (charsInput.size() > 0) {
return charsInput.get(0);
}
return (0);
}
}
private static int Solution(String s) {
// to check is values has been considered once
Set<String> set=new HashSet<String>();
// main loop
for (int i = 0; i < s.length(); i++) {
String temp = String.valueOf(s.charAt(i));
//rest of the values
String sub=s.substring(i+1);
if (set.add(temp) && !sub.contains(temp)) {
return i;
}
}
return -1;
}
I am suppose to use Boolean to check if the string is palindrome. I'm getting an error, not sure what I am doing wrong. My program already has 3 strings previously imputed by a user. Thank you, I am also using java
public boolean isPalindrome(String word1, String word2, String word3){
int word1Length = word1.length();
int word2Length = word2.length();
int word3Length = word3.length();
for (int i = 0; i < word1Length / 2; i++)
{
if (word1.charAt(i) != word1.charAt(word1Length – 1 – i))
{
return false;
}
}
return isPalindrome(word1);
}
for (int i = 0; i < word2Length / 2; i++)
{
if (word2.charAt(i) != word2.charAt(word2Length – 1 – i))
{
return false;
}
}
return isPalindrome(word2);
}
for (int i = 0; i < word3Length / 2; i++)
{
if (word3.charAt(i) != word3.charAt(word3Length – 1 – i))
{
return false;
}
}
return isPalindrome(word3);
}
// my output should be this
if (isPalindrome(word1)) {
System.out.println(word1 + " is a palindrome!");
}
if (isPalindrome(word2)) {
System.out.println(word2 + " is a palindrome!");
}
if (isPalindrome(word3)) {
System.out.println(word3 + " is a palindrome!");
}
You could do a method for it like this:
First you build a new String and than you check if it is equal.
private static boolean test(String word) {
String newWord = new String();
//first build a new String reversed from original
for (int i = word.length() -1; i >= 0; i--) {
newWord += word.charAt(i);
}
//check if it is equal and return
if(word.equals(newWord))
return true;
return false;
}
//You can call it several times
test("malam"); //sure it's true
test("hello"); //sure it's false
test("bob"); //sure its true
I am stuck at solving this problem. Below is what I came up with most:
Question: Write the boolean method public static boolean isSubstring(String x, String y) that takes two Strings x and y as arguments and returns true if an only if String x is a substring of String y. String x is a substring of String y if and only if all characters in x appear consecutively in y. For this problem, the only String methods you may use are length( ) and charAt( ). If you use any other String methods, you will receive no credit for this problem.
import java.util.Scanner;
public class question {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter String 1:");
String String1 = input.nextLine();
System.out.print("Enter String 2:");
String String2 = input.nextLine();
if(isSubstring(String1,String2)){
System.out.println("True");
} else {
System.out.println("False");
}
}
public static boolean isSubstring(String x, String y) {
int count = 0, xIndex = 0, yIndex = 0;
boolean sub = false;
while(!sub && yIndex < y.length()){
if(y.charAt(yIndex) == x.charAt(yIndex)){
xIndex++;
count++;
} else {
if(count == x.length()){
sub = true;
}
}
yIndex++;
}
return sub;
}
}
This checks if s2 is a substring of s1.
public static boolean isSubstring(String s1, String s2){
if(s1.length()<s2.length()) return false;
if(s1.length()==s2.length()) return s1.equals(s2);
for(int i=0;i<=s1.length()-s2.length();i++){
if(s1.charAt(i)==s2.charAt(0)){
int matchLength=1;
for(int j=1;j<s2.length();j++){
if(s1.charAt(i+j)!=s2.charAt(j)){
break;
}
matchLength++;
}
if(matchLength==s2.length()) return true;
}
}
return false;
}
You're not guarding xIndex for overflow. Guess if substring y is placed at end of x it fails. Also mind the case where x is of smaller length than x, could just return false then as optimization if you keep lengths first in local vars at start of method
public class Task_1_9 {
public static boolean isSubstring(String s1, String s2){
if (s1.length() != s2.length()) return false;
int count = 0;
int i = 0;
int j = 0;
String s3 = s2 + s2;
while (j < s3.length() && count < s1.length()){
if (s1.charAt(i) == s3.charAt(j)){
count++;
i++;
} else {
count = 0;
}
j++;
}
return count == s1.length() ? true : false;
}
public static void main(String[] args) {
System.out.println(isSubstring("waterbottle","erbottlewat"));
}
}
I know this problem is probably best served with DP, but I was wondering if it was possible to do it with recursion as a brute force way.
Given a set of words, say {"sales", "person", "salesperson"}, determine which words are compound (that is, it is the combination of 2 or more words in the list). So in this case, salesperson = sales + person, and is compound.
I based my answer heavily off of this problem: http://www.geeksforgeeks.org/dynamic-programming-set-32-word-break-problem/
public static void main(String args[]) throws Exception {
String[] test = { "salesperson", "sales", "person" };
String[] output = simpleWords(test);
for (int i = 0; i < output.length; i++)
System.out.println(output[i]);
}
static String[] simpleWords(String[] words) {
if (words == null || words.length == 0)
return null;
ArrayList<String> simpleWords = new ArrayList<String>();
for (int i = 0; i < words.length; i++) {
String word = words[i];
Boolean isCompoundWord = breakWords(words, word);
if (!isCompoundWord)
simpleWords.add(word);
}
String[] retVal = new String[simpleWords.size()];
for (int i = 0; i < simpleWords.size(); i++)
retVal[i] = simpleWords.get(i);
return retVal;
}
static boolean breakWords(String[] words, String word) {
int size = word.length();
if (size == 0 ) return true;
for (int j = 1; j <= size; j++) {
if (compareWords(words, word.substring(0, j)) && breakWords(words, word.substring(j, word.length()))) {
return true;
}
}
return false;
}
static boolean compareWords(String[] words, String word) {
for (int i = 0; i < words.length; i++) {
if (words[i].equals(word))
return true;
}
return false;
}
The problem here is now that while it successfully identifies salesperson as a compound word, it will also identify sales and person as a compound word. Can this code be revised so that this recursive solution works? I'm having trouble coming up with how I can easily do this.
Here is a solution with recursivity
public static String[] simpleWords(String[] data) {
List<String> list = new ArrayList<>();
for (String word : data) {
if (!isCompound(data, word)) {
list.add(word);
}
}
return list.toArray(new String[list.size()]);
}
public static boolean isCompound(String[] data, String word) {
return isCompound(data, word, 0);
}
public static boolean isCompound(String[] data, String word, int iteration) {
if (data == null || word == null || word.trim().isEmpty()) {
return false;
}
for (String str : data) {
if (str.equals(word) && iteration > 0) {
return true;
}
if (word.startsWith(str)) {
String subword = word.substring(str.length());
if (isCompound(data, subword, iteration + 1)) {
return true;
}
}
}
return false;
}
Just call it like this:
String[] data = {"sales", "person", "salesperson"};
System.out.println(Arrays.asList(simpleWords(data)));
I'm trying to implement String method contains() without using the built-in contains() method.
Here is what I have so far:
public static boolean containsCS(String str, CharSequence cs) {
char[] chs = str.toCharArray();
int i=0,j=chs.length-1,k=0,l=cs.length();
//String str = "Hello Java";
// 0123456789
//CharSequence cs = "llo";
while(i<j) {
if(str.charAt(i)!=cs.charAt(k)) {
i++;
}
if(str.charAt(i)==cs.charAt(k)) {
}
}
return false;
}
I was just practicing my algorithm skills and got stuck.
Any advice?
Using Only 1 Loop
I did some addition to Poran answer and It works totally fine:
public static boolean contains(String main, String Substring) {
boolean flag=false;
if(main==null && main.trim().equals("")) {
return flag;
}
if(Substring==null) {
return flag;
}
char fullstring[]=main.toCharArray();
char sub[]=Substring.toCharArray();
int counter=0;
if(sub.length==0) {
flag=true;
return flag;
}
for(int i=0;i<fullstring.length;i++) {
if(fullstring[i]==sub[counter]) {
counter++;
} else {
counter=0;
}
if(counter==sub.length) {
flag=true;
return flag;
}
}
return flag;
}
This should work fine..I am printing execution to help understand the process.
public static boolean isSubstring(String original, String str){
int counter = 0, oLength = original.length(), sLength = str.length();
char[] orgArray = original.toCharArray(), sArray = str.toCharArray();
for(int i = 0 ; i < oLength; i++){
System.out.println("counter at start of loop " + counter);
System.out.println(String.format("comparing %s with %s", orgArray[i], sArray[counter]));
if(orgArray[i] == sArray[counter]){
counter++;
System.out.println("incrementing counter " + counter);
}else{
//Special case where the character preceding the i'th character is duplicate
if(counter > 0){
i -= counter;
}
counter = 0;
System.out.println("resetting counter " + counter);
}
if(counter == sLength){
return true;
}
}
return false;
}
Hints:
Use a nested loop.
Extracting the chars to an array is probably a bad idea. But if you are going to do it, you ought to use it!
Ignore the suggestion to use fast string search algorithms. They are only fast for large scale searches. (If you look at the code for String.indexOf, it just does a simple search ...)
As JB Nizet suggested, here is the actual code for contains():
2123 public boolean contains(CharSequence s) {
2124 return indexOf(s.toString()) > -1;
2125 }
And here is the code for indexOf():
1732 public int indexOf(String str) {
1733 return indexOf(str, 0);
1734 }
Which leads to:
1752 public int indexOf(String str, int fromIndex) {
1753 return indexOf(value, offset, count,
1754 str.value, str.offset, str.count, fromIndex);
1755 }
Which finally leads to:
1770 static int indexOf(char[] source, int sourceOffset, int sourceCount,
1771 char[] target, int targetOffset, int targetCount,
1772 int fromIndex) {
1773 if (fromIndex >= sourceCount) {
1774 return (targetCount == 0 ? sourceCount : -1);
1775 }
1776 if (fromIndex < 0) {
1777 fromIndex = 0;
1778 }
1779 if (targetCount == 0) {
1780 return fromIndex;
1781 }
1782
1783 char first = target[targetOffset];
1784 int max = sourceOffset + (sourceCount - targetCount);
1785
1786 for (int i = sourceOffset + fromIndex; i <= max; i++) {
1787 /* Look for first character. */
1788 if (source[i] != first) {
1789 while (++i <= max && source[i] != first);
1790 }
1791
1792 /* Found first character, now look at the rest of v2 */
1793 if (i <= max) {
1794 int j = i + 1;
1795 int end = j + targetCount - 1;
1796 for (int k = targetOffset + 1; j < end && source[j] ==
1797 target[k]; j++, k++);
1798
1799 if (j == end) {
1800 /* Found whole string. */
1801 return i - sourceOffset;
1802 }
1803 }
1804 }
1805 return -1;
1806 }
I came up with this:
public static boolean isSubString(String s1, String s2) {
if (s1.length() > s2.length())
return false;
int count = 0;
//Loop until count matches needle length (indicating match) or until we exhaust haystack
for (int j = 0; j < s2.length() && count < s1.length(); ++j) {
if (s1.charAt(count) == s2.charAt(j)) {
++count;
}
else {
//Redo iteration to handle adjacent duplicate char case
if (count > 0)
--j;
//Reset counter
count = 0;
}
}
return (count == s1.length());
}
I have recently stumbled upon this problem, and though I would share an alternative solution. I generate all the sub strings with length of the string we looking for, then push them into a hash set and check if that contains it.
static boolean contains(String a, String b) {
if(a.equalsIgnoreCase(b)) {
return true;
}
Set<String> allSubStrings = new HashSet<>();
int length = b.length();
for(int i=0; i<a.length(); ++i) {
if(i+length <= a.length()) {
String sub = a.substring(i, i + length);
allSubStrings.add(sub);
}
}
return allSubStrings.contains(b);
}
public static boolean contains(String large, String small) {
char[] largeArr = large.toCharArray();
char[] smallArr = small.toCharArray();
if (smallArr.length > largeArr.length)
return false;
for(int i = 0 ; i <= largeArr.length - smallArr.length ; i++) {
boolean result = true ;
for(int j = 0 ; j < smallArr.length ; j++) {
if(largeArr[i+j] != smallArr[j]) {
result = false;
break;
}
result = result && (largeArr[i+j]==smallArr[j]);
}
if(result==true) {return true;}
}
return false;
}
Certainly not the most efficient solution due to the nested loop, but it seems to work pretty well.
private static boolean contains(String s1, String s2) {
if (s1.equals(s2)) return true;
if (s2.length() > s1.length()) return false;
boolean found = false;
for (int i = 0; i < s1.length() - s2.length(); i++) {
found = true;
for (int k = 0; k < s2.length(); k++)
if (i + k < s1.length() && s1.charAt(i + k) != s2.charAt(k)) {
found = false;
break;
}
if (found) return true;
}
return false;
}
It can be done using a single loop.
public boolean StringContains(String full, String part) {
long st = System.currentTimeMillis();
if(full == null || full.trim().equals("")){
return false;
}
if(part == null ){
return false;
}
char[] fullChars = full.toCharArray();
char[] partChars = part.toCharArray();
int fs = fullChars.length;
int ps = partChars.length;
int psi = 0;
if(ps == 0) return true;
for(int i=0; i< fs-1; i++){
if(fullChars[i] == partChars[psi]){
psi++; //Once you encounter the first match, start increasing the counter
}
if(psi == ps) return true;
}
long et = System.currentTimeMillis()- st;
System.out.println("StringContains time taken =" + et);
return false;
}