I am currently solving one of Leetcode's questions on strings. I need to check that all of my string literals are letters.
I have the attached code below:
for (int i = 0; i < s.length(); i++) {
char character = s.charAt(i);
if (!Character.isLetter(character))
return s;
lastIndex[character - 'a'] = i;
}
What is the time complexity of checking that a string contains all letters?
I think it's O(n) though since the check will be done for all the characters in the string.
Thanks.
Related
This program is intended to match a string to another string and calculate the number common substrings they share. For some reason, it always prints the same incorrect values. Using the same methods, how can I make this code work as I intended it to?
public static void main(String[] args) {
String secret = "word";
String guess = "gzek";
int count = 0;
int length = secret.length();
int guess_length = guess.length();
for(int i=0;i<length-1;i++){
if(secret.substring(i, i).equals(guess.substring(i, i))){
count ++;
}
}
System.out.println(count);
}
According to its JavaDoc, the end index parameter of the substring() method is exclusive:
#param beginIndex the beginning index, inclusive.
#param endIndex the ending index, exclusive.
This means that secret.substring(i, i) returns the sub-string from i to i-1, which is always the empty string "". Therefore, secret.substring(i, i).equals(guess.substring(i, i)) always compares "" with "" and is always true. Your code effectively counts the number of characters in guess.
If you want to compute all sub-strings of a string s, you need two loops, one for the start index and one for the end index:
for (int i = 0; i < s.length(); i++) {
for (int j = i; j < s.length(); j++) {
String substring = s.substring(i, j + 1);
// further code ...
}
}
Note that this only computes the sub-strings of one string. If I understood your question correctly, you want to compute all common sub-strings of two strings. To do this, you will need a total of four nested loops. This is going to be very slow even for small strings. There are of course much faster approaches, but they are also more complex.
i have to write a program which will reverse all words in a string, but all symbols should stay on previous position for example: "a1bcd efg!h" => "d1cba hgf!e". I wrote a simple program which can reverse all words/symbols, but I have no idea how to make it like in example
public void reverseWordInMyString(String str) {
String[] words = str.split(" ");
String reversedString = "";
for (int i = 0; i < words.length; i++) {
String word = words[i];
String reverseWord = "";
for (int j = word.length()-1; j >= 0; j--) {
reverseWord = reverseWord + word.charAt(j);
}
reversedString = reversedString + reverseWord + " ";
}
System.out.println(reversedString);
}
It's a good start. The question is just that tricky.
Your current approach uses a single 'accumulator' which starts at the end of the string and moves back to the start: The j in for (int j =...).
You'll need two accumulators to complete this homework assignment: One going from the front to the back, which steadily increments (so, that'll be for (int i = 0; i < word.length(); i++)), and one which starts at the end and decrements, but not steadily.
The idea is: As you go forward, you inspect the character you find at position i. Then, you use an if, as the question asks you to do different things depending on a condition:
if the character at i is a special character, just add it.
else, add the last non-special character in the string we haven't yet added.
the if case is trivial. The else case is not. That's where your second accumulator comes in: This one will track where you're at in the string, from the end. This is a loop-in-loop. What you'll need to:
repeat the following algorithm:
If the character at 'j' (which goes from end to start) is a special character, decrement j, and restart this algorithm
Otherwise, that's the 'last non-special character we havent yet added', so add that, decrement j, and escape this algorithm.
The above can be done with, for example, a while or do/while loop. It'll be inside your for loop.
Good luck!
NB: This isn't the only way to do it. For example, you could also eliminate all special characters from the input, do a basic reverse on every word inside, which is a lot simpler than what you have now, as string has a .reverse() method these days, and then, after all that, go through your original input character by character, and for each special character you find, insert that character at that position in your output string. That works too. Whichever strategy you prefer!
according to www.geeksforgeeks.org
The Problem:
Given a string, that contains special character together with alphabets (‘a’ to ‘z’ and ‘A’ to ‘Z’), reverse the string in a way that special characters are not affected.
Solution:
Create a temporary character array say temp[].
Copy alphabetic characters from given array to temp[].
Reverse temp[] using standard string reversal algorithm.
Now traverse input string and temp in a single loop. Wherever there is alphabetic character is input string, replace it with current character of temp[].
Algorithm:
1) Let input string be 'str[]' and length of string be 'n'
2) l = 0, r = n-1
3) While l is smaller than r, do following
a) If str[l] is not an alphabetic character, do l++
b) Else If str[r] is not an alphabetic character, do r--
c) Else swap str[l] and str[r]
Java Code:
public static void main(String[] args){
String s = "Thi!s is a sa5mpl?e sentence.";
String[] words = s.split("\\s+");
System.out.println("Result:" + reverse(s));
//Output: sih!T si a el5pma?s ecnetnes.
}
public static String reverse(String input)
{
String[] words = input.split("\\s+");
String last_str = "";
for(int j=0;j<words.length;j++){
char[] str = words[j].toCharArray();
int r = str.length - 1, l = 0;
// Traverse string from both ends until
// 'l' and 'r'
while (l < r)
{
// Ignore special characters
if (!Character.isAlphabetic(str[l]))
l++;
else if(!Character.isAlphabetic(str[r]))
r--;
// Both str[l] and str[r] are not spacial
else
{
str[l] ^= str[r];//swap using triple XOR
str[r] ^= str[l];
str[l] ^= str[r];
l++;
r--;
}
}
last_str = last_str + new String(str) + " ";
}
// Initialize left and right pointers
return last_str;
}
}
I would approach this as follows:
Keep track of where the current word starts (or, equivalently, where the last non-word character was). This will be updated as we go along.
Scan the input string. Every time a non-word character (special character or space) is found, output the reverse of the current word and then the non-word character. You can output the reverse of the current word by indexing backwards from just before the non-word character to the start of the current word. (Note that the current word might be empty; for example, two special characters in a row).
For the output area, I recommend a StringBuilder rather than a String; this will be more efficient.
In code, it might look something like this (where I've changed the method to return the result rather than print it to the console):
public String reverseWordInMyString(String str) {
StringBuilder output = new StringBuilder(str.length()); // initialize full capacity
int curWordStart = 0;
// scan the input string
for (int i = 0; i < str.length(); i++) {
char curLetter = str.charAt(i);
if (!Character.isLetter(char)) {
// the current word has ended--output it in reverse
for (int j = i-1; j >= curWordStart; j--) {
output.append(str.charAt(j));
}
// output the current letter
output.append(curLetter);
// the next current word starts just after the current letter
curWordStart = i + 1;
}
}
// The last current word (if any) ends with the end of string,
// not a special character, so add it (reversed) as well to output
for (int j = str.length() - 1; j >= curWordStart; j--) {
output.append(str.charAt(j));
}
return output.toString();
}
I'm looking for a way to compare two strings to each other character by character.
It should show whether there are other characters which don't appear in both strings.
Does someone have a solution for?
for(int j=0; j < min; j++) {
s1 = w1.substring(j,j+1);
s2 = w2.substring(j,j+1);
if (!s1.equalsIgnoreCase(s2) ){
counter++;
}
}
This only looks sequential for differences. But I want to find out whether there are differences between those two strings at all.
So **abc** and **cab** should count as a hit
I think what you want is to show that 2 strings have the same letters and the same amount of each letter. Use 2 hashsets, where the key is the character and the value is the number of occurrence in the string. you'll have one hashset for each string, then loop through the string add the characters to the set and compare to see if the sets are equal.
Turn them into charArrays and add the differences to an empty string as a for loop scans through them, for instance
String a = "abc";
char[] aa = a.toCharArray();
String b = "cba";
char[] bb = b.toCharArray();
String dif;
public void differ() {
for(int i = 0; i < aa.length - 1; i++) {
if(!aa[i].equals(bb[i])) {
dif += aa[i];
}
}
}
I believe running differ() would return "ac" because they both have b in the middle. Is this what you wanted?
My question is thus:
Suppose you have String myString = "SOME_CHARACTERS_THAT_NEED_MODIFICATION"; that you would want to have look like String modifiedString = "Some Characters That Need Modification". The "pure String" way to do it (and the case-independent way) would (optimize this as necessary):
//obtaining the locations of all the occurrences of '_'
int activeIndex = 0;
ArrayList <Integer> indexList = new ArrayList<Integer>();
while (activeIndex != -1)
{
activeIndex = myString.indexOf('_', activeIndex + 1);
indexList.add(new Integer(activeIndex));
}
//replacing all '_' with ' '
String tempString = myString.replace('_', ' ');
//declaring empty modifiedString
String modifiedString;
//lowercasing all characters that are not first characters of a word (here, a word is defined as being terminated by '_' or newline
for (int x = 0; x < indexList.size(); x++)
{
modifiedString += tempString.substring(indexList.get(x), indexList.get(x)+1);
if (x != indexList.size() - 1)
//appending first uppercase character of word plus lowercased characters of the rest of the word
modifiedString += tempString.subString(indexList.get(x)+1,indexList.get(x+1)).toLowerCase();
else
//we are near the end of the String (as far as ' ' is concerned)
modifiedString += tempString.substring(index.get(x), tempString.length().toLowerCase());
}
//moving this modified String to modifiedString
modifiedString = tempString;
The other way I was proposing to do this would have been to dump myString into an array of characters, and then do array-based manipulation of all the characters. This would be easy in C++; a String is both an array of characters and an Object there! My question is, however, would both algorithms have the same complexity? //As a character array, I could probably do some arithmetic, assuming that the alphanumeric characters are numerically in the ASCII range (0 through 127). In fact, (int)uppercaseChar == (int)lowercaseChar - 32; for any of the uppercaseChar ranging from A-Z and any corresponding lowercaseChar ranging from a-z.
The char[] way to do would probably be something like (may need optimization)
//declaring necessary variables and containers
int activeIndex = 0;
ArrayList<Integer> indexList = new ArrayList<Integer>();
while (activeIndex != -1)
{
//finding all '_'
activeIndex = myString.indexOf('_', activeIndex + 1);
//pushing it to indexArray
indexArray.add(new Integer(activeIndex));
}
//dumping String to char[]
char[] charArray = myString.toCharArray();
for (int x = 0; x < indexArray.size(); x++)
{
//making every '_' a ' '
charArray[indexArray.get(x)] = ' ';
//lowercasing every capitalized character that isn't a first character in a word
}
would both algorithms have the same complexity?
No. If the input string holds n consecutive underscores, then
for (int x = 0; x < indexList.size(); x++)
modifiedString += tempString.substring(indexList.get(x), indexList.get(x)+1);
will append a single underscore n times. Since the old value of modifiedString has to be copied every time around the loop at linear time cost, the whole algorithm takes quadratic time.
By contrast, the "char[] approach" takes linear time.
I think, doing it through ASCII or unicode way would be better.
Iterate through the array, Except for the first character, keep replacing all characters to lower case(through arithmetic calculation that you talked about) until you find a character whose ascii value is same as '_'. Once you get this character, again except for the first character, replace everything else with lower case, until again you get '_'. This can be done in just one iteration.
Whereas string.replace all would itself take one iteration just to replace.And your code would still look lot cleaner.
Note :Assuming the input pattern to be exactly the same.
Extending #zerocool 's answer, I found out the code to the way to do this optimally. It is something like:
private char[] charArray = myString.toCharArray();
int indexOfUnderscore = -1;
for (int x = 0; x < charArray.length; x++)
{
if (charArray[x] == '_')
{
charArray[x] = ' ';
indexOfUnderscore = x;
}
else
{
if (x > indexOfUnderscore + 1)
{
charArray[x] = (char)((int)charArray[x] + 32);
}
}
}
The algorithmic complexity of the above code would be, ignoring String.toCharArray(), O(length). We could then just say something like private String modifiedString = new String(charArray); to get it back as a String. I feel the character-array way is syntactically simpler to understand than the built-in String functions.
#zerocool, I wish I would have seen your answer when I thought up this.
This question already has answers here:
How to map character to numeric position in java?
(7 answers)
Closed 5 years ago.
How to get numeric position of alphabets in java ?
Suppose through command prompt i have entered abc then as a output i need to get 123 how can i get the numeric position of alphabets in java?
Thanks in advance.
String str = "abcdef";
char[] ch = str.toCharArray();
for(char c : ch){
int temp = (int)c;
int temp_integer = 96; //for lower case
if(temp<=122 & temp>=97)
System.out.print(temp-temp_integer);
}
Output:
123456
#Shiki for Capital/UpperCase letters use the following code:
String str = "DEFGHI";
char[] ch = str.toCharArray();
for(char c : ch){
int temp = (int)c;
int temp_integer = 64; //for upper case
if(temp<=90 & temp>=65)
System.out.print(temp-temp_integer);
}
Output:
456789
Another way to do this problem besides using ASCII conversions is the following:
String input = "abc".toLowerCase();
final static String alphabet = "abcdefghijklmnopqrstuvwxyz";
for(int i=0; i < input.length(); i++){
System.out.print(alphabet.indexOf(input.charAt(i))+1);
}
Convert each character to its ASCII code, subtract the ASCII code for "a" and add 1. I'm deliberately leaving the code as an exercise.
This sounds like homework. If so, please tag it as such.
Also, this won't deal with upper case letters, since you didn't state any requirement to handle them, but if you need to then just lowercase the string before you start.
Oh, and this will only deal with the latin "a" through "z" characters without any accents, etc.
char letter;
for(int i=0; i<text.length(); i++)
{
letter = text.charAt(i);
if(letter>='A' && letter<='Z')
System.out.println((int)letter - 'A'+1);
if(letter>='a' && letter<= 'z')
System.out.println((int)letter - 'a'+1);
}
This depends on the alphabet but for the english one, try this:
String input = "abc".toLowerCase(); //note the to lower case in order to treat a and A the same way
for( int i = 0; i < input.length(); ++i) {
int position = input.charAt(i) - 'a' + 1;
}
First you need to write a loop to iterate over the characters in the string. Take a look at the String class which has methods to give you its length and to find the charAt at each index.
For each character, you need to work out its numeric position. Take a look at this question to see how this could be done.
just logic I can suggest take two arrays.
one is Char array
and another is int array.
convert ur input string to char array,get the position of char from char and int array.
dont expect source code here
String word = "blah blah";
for(int i =0;i<word.length;++i)
{
if(Character.isLowerCase(word.charAt(i)){
System.out.print((int)word.charAt(i) - (int)'a'+1);
}
else{
System.out.print((int)word.charAt(i)-(int)'A' +1);
}
}