I came across a question on codingbat and the question is:
Given a string, return a new string made of 3 copies of the last 2 chars of the original string. The string length will be at least 2.
I solved the problem and the solution (below) is a better than mine, however, there is a problem with the solution code, when the string length is less than 2, say the length is only 1. str index will be -1. will the code still work? why does the site say the solution is correct?
public String extraEnd(String str) {
String end = str.substring(str.length()-2);
return end + end + end;
The website will try to give you as many tests as possible to make sure it's mostly free of bugs, however some do slip through the crack and make exceptions. The code below is one that works through all tests given if you want to give it a go;
public String extraFront(String str) {
if (str.length() <= 2)
return str+str+str;
return str.substring(0,2)+str.substring(0,2)+str.substring(0,2);
}
It seems that you're correct with the code, the index would be -1. Maybe follow it up with the challenge on String 2, it'll come in handy. Wish you best of luck!
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 months ago.
This post was edited and submitted for review 8 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
I am new to java. Trying to create a function to remove a given string "arg" from myString which is previously set and return a new string not affecting myString. I believe i could solve this problem if it was not for all non alphabetical character of arg should remain in the string. so if arg has a 7 in it that should still be included in the final string. characters being removed are case insensitive as well.
I have edited the previous code and post, i can now run my code but I am not getting the correct results, I am trying to remove all numbers from arg before using it to remove all the characters. myString method is previously defined and working properly to return a string.
For examplecurrent string "my lucky numbers are 6, 8, and 19.", calling remove("ra6") would return "my lucky numbes e 6, 8, nd 19."
or "my lucky numbers are 6, 8, and 19.", calling remove("6,.") would return "my lucky numbers are 6, 8, and 19."
thank you!
public String remove(String arg) {
char[] charArray=arg.toCharArray();
String result="";
String newString="";
for (int i = 0; i < charArray.length; i++) {
if (!Character.isDigit(charArray[i])) {
result = result + charArray[i];
return result;}}
if (myString==null || myString=="") {
this.myString="";}
if (myString!=null) {
newString= myString.replaceAll(result,"");}
return newString;
}
Here is one way using streams. Just create a stream of characters via the chars() method and allow only letters to pass thru. Then each character to a String and join them together. Then remove that result from the original passed string.
String myString = "abcdTLK123efgh";
String arg = "TLK###123";
String result = remove(arg, myString);
System.out.println("Result = " + result);
prints
Result = abcd123efgh
The method
I modified the method to accept two strings.
the one to remove characters(arg).
and the from which to remove modified arg from myString
it works by
streaming all the characters of arg.
filtering out all but letters and digits
joining them as a string.
and then removing that filtered string from the myString.
public static String remove(String arg, String myString) {
if (myString == null || myString.isBlank()) {
return "";
}
return arg.chars().filter(
ch -> Character.isLetter(ch))
.mapToObj(Character::toString)
.collect(Collectors.collectingAndThen(
Collectors.joining(),
str -> myString.replace(str, "")));
}
Note: If myString is null then assigning an empty string to it will contain nothing to change. Nor an initial empty string. So I just returned an empty String if those conditions existed.
I believe i could solve this problem if it was not for all non alphabetical character of arg should remain in the string.
The good news is that you can solve it yourself.
The bad news is that the code above is in such a mess that it would be difficult for you to fix it by yourself. (Given your current level understand of Java syntax, way of working, etcetera.)
(Also, there is a long more wrong than the "if it were not for ..." ...)
So here is what I advise you to do.
Save a copy of the current version of the (entire) class somewhere safe so that you can look it again if you need to, or revert to it.
Develop a model of what the method needs to do and how it will do it; see below.
Delete all lines of code between the first { and last } shown in the question. Yes. Delete them.
Compose the new version of the code, one line at a time. As follows:
Add a line.
Compile the code (or let the IDE compile it for you).
Read the compilation error(s) that just appeared.
Understand the compilation errors.
Make the necessary changes to fix the compilation errors. Don't rely on your IDE's facility for suggesting corrections. (The IDE doesn't understand your code, what you are going to add next, or what you are trying to achieve. Its suggestions are liable to be unhelpful or even wrong.)
Repeat until you have dealt with all of the compilation errors that were introduced.
Now you are ready to add another line.
Once you have a complete method, you can then try to run it.
You will most likely find that the code doesn't work. But at least it will be valid Java code. And in the process of doing 4. above, you will (hopefully!) have learned enough Java syntax to be able to read and understand the code that you wrote. And 2. will help you understand what the code you are writing should do.
My other observation is that it looks like you have been adding and removing statements to this code with no clear understanding of what they do or what needs to happen. Maybe you started with some code that did something else ... correctly ... but it is hard to tell now.
Changing things randomly to try to make the code work is not a sensible approach. It rarely works. You need to have a model (or plan) in your head or on paper (e.g. as pseudo-code or flowcharts) about how the code ought to work.
Programming is about 1) developing the model, then 2) translating the model into code. The first part is the hard (and interesting) part. But if you skip the first part, the second part is an essentially random process, and unlikely to succeed.
The problem with starting with someone else's code is that you risk not developing a mental model of how that code works. Let alone the model that you are aiming for.
Finally, a professional programmer will use a version control system for their source code, and make relatively frequent commits of their code to their repository. Among other things, that allows them to quickly "roll back" to an earlier version if they need to, or keep track of exactly what they changed.
It is probably too early for you to learn about (say) using Git ... but it would help you solve your problem if you could just "roll back" all of the changes where you were "messing" with the code to get it to work.
I am trying to solve this question on LeetCode:
A string s is nice if, for every letter of the alphabet that s contains, it appears both in uppercase and lowercase. For example, "abABB" is nice because 'A' and 'a' appear, and 'B' and 'b' appear. However, "abA" is not because 'b' appears, but 'B' does not.
Given a string s, return the longest substring of s that is nice. If there are multiple, return the substring of the earliest occurrence. If there are none, return an empty string.
For s = "YazaAay", the expected output is: "aAa"
One of the top voted solutions uses a Divide and Conquer approach:
class Solution {
public String longestNiceSubstring(String s) {
if (s.length() < 2) return "";
char[] arr = s.toCharArray();
Set<Character> set = new HashSet<>();
for (char c: arr) set.add(c);
for (int i = 0; i < arr.length; i++) {
char c = arr[i];
if (set.contains(Character.toUpperCase(c)) && set.contains(Character.toLowerCase(c))) continue;
String sub1 = longestNiceSubstring(s.substring(0, i));
String sub2 = longestNiceSubstring(s.substring(i+1));
return sub1.length() >= sub2.length() ? sub1 : sub2;
}
return s;
}
}
I understand how it works, but not the intuition behind using a Divide and Conquer approach. In other words, if I revisit the problem again after a few days/weeks after I have forgotten everything about it, I won't be able to realize it is a Divide and Conquer problem.
What is that 'thing' that makes it solvable by a Divide and Conquer approach?
This is how the algorithm could be described in plain English:
If the entire string is nice, we are done.
Otherwise, there must be a character which exists in only one case. Such a character naturally divides the string into two substrings. Conquer each of them individually, and compare results.
Edit: BTW, I don't think it is a good example of D&C problem. The point is, once we encounter the first "bad" character, the substring to the left of it is nice. There is no need to descend into it. Just record its length and keep going. A simple loop it is.
Divide-And-Conquer, to paraphrase wikipedia, is most appropriate when a problem can be broken down into "2 or more subproblems". The solution here checks that the input string meets the condition, then breaks it in two at each character, and recursively checks the strings meet the condition until there is no solution. Generally, the application of divide-and-conquer is easy to get a feel for when the problem can be subdivided symmetrically, such as in the DeWall algorithm for computing the delaunay triangulation for a set of points (http://vcg.isti.cnr.it/publications/papers/dewall.pdf - cool stuff).
What sets the substring problem apart in this instance is it checks all (edit:) possible viable subdivisions by incrementing the line of subdivision. To clarify for anyone who might be confused, this is necessary because the string can't be split down the middle, else you might be splitting a substring like "aAaA" apart and returning only half of it in the end. This kind of meets the more condition in "two or more problems", but I agree it's not intuitive in this instance.
Hope this helps, I had to learn about this a lot recently while implementing the referenced algorithm. Someone with more experience might have a better answer.
I have this code, but it seems pretty unwieldy. Is there a more canonical way of doing so in Java?
public boolean oneDiff(String from, String s) {
if (from.length()!=s.length()) return false;
int differences = 0;
for (int charIndex = 0;charIndex<from.length();charIndex++) {
if (from.charAt(charIndex)!=s.charAt(charIndex)) differences++;
}
return (differences==1);
}
I agree with #mk. However to minimize the loop execution you should not run the loop till the string ends. Instead you can break the loop as soon as the difference becomes greater than 1. Like this:
for (int charIndex = 0;charIndex<from.length();charIndex++) {
if (from.charAt(charIndex)!=s.charAt(charIndex)) differences++;
if(differences > 1) break;
}
return (differences==1);
This will help in faster execution by loop optimization if this is what you want.
Nope, that really is the best way!
There's nothing built-in because this isn't something you need to do often. The closest trick is doing an xor on two integers, and then getting the Hamming Weight using bitCount, in order to check for how many flipped bits they have in common:
Integer.bitCount(int1 ^ int2)
But there's nothing like that for Strings - it's not a common case, so you have to code your own. And the way you've coded it seems fine - you really do have to loop over every character. I guess you could shorten the variable names and remove the parens around your return, but that's just cosmetic.
My roommate's teacher gave them a assignment to implement string length method in JAVA?
we have thought out two ways.
Check the element,and when get the out of bounds exception,it means the end of string,we catch this exception,then we can get the length.
Every time a string is pass to calculate the length,we add the special character to the end of it,it can be '\0',or "A",etc..
But we all think this two way may can finish the assignment,but they are bad(or bad habit to do with exception),it's not cool.
And we have googled it,but don't get what we want.
Something like this?
int i = 0;
for (char ch : string.toCharArray()) {
i++;
}
The pseudo-code you probably want is:
counter = 0
for(Character c in string) {
counter = counter + 1
}
This requires you to find a way to turn a Java String into an array of characters.
Likely the teacher is trying to make his or her students think, and will be satisfied with creative solutions that solve the problem.
None of these solutions would be used in the real world, because we have the String.length() method. But the creative, problem-solving process you're learning would be used in real development.
"1. Check the element,and when get the out of bounds exception,it means the end of string,we catch this exception,then we can get the length."
Here, you're causing an exception to be thrown in the normal case. A common style guideline is for exceptions to be thrown only in exceptional cases. Compared to normal flow of control, throwing an exception can be more expensive and more difficult to follow by humans.
That said, this one of your ideas has a potential advantage for very long strings. All of the posted answers so far run in linear time and space. The time and/or additional space they take to execute is proportional to the length of the string. With this approach, you could implement an O(log n) search for the length of the string.
Linear or not, it's possible that the teacher would find this approach acceptable for its creativity. Avoid if the teacher has communicated the idea that exceptions are only for exceptional cases.
"2. Every time a string is pass to calculate the length,we add the special character to the end of it,it can be '\0',or "A",etc.."
This idea has a flaw. What happens if the string contains your special character?
EDIT
A simple implementation would be to get a copy of the underlying char array with String.toCharArray(), then simply take its length. Unlike your ideas, this is not an in-place approach - making the copy requires additional space in memory.
String s = "foo";
int length = s.toCharArray().length;
Try this
public static int Length(String str) {
str = str + '\0';
int count = 0;
for (int i = 0; str.charAt(i) != '\0'; i++) {
count++;
}
return count;
}
What about:
"your string".toCharArray().length
I'm learning Java, and I'm completing some problems tasked to me.
I've come across a specific problem and I feel like the answer is so simple, but I just can't find it.
I need to check if given string ends with the first two characters it begins with. For example, "edited" (begins and ends with "ed")
I've tried using the java endsWith and startsWith, but I keep getting an error
start = text.startsWith(text.substring(0,2));
Yeilds
Error: incompatible types
required: java.lang.String
found: boolean
Any help would be appreciated.
Thankyou.
You're calling startsWith when you don't need to - you know it starts with the first two characters, by definition :)
You could have:
String start = text.substring(0, 2);
boolean valid = text.endsWith(start);
Or just collapse the two:
boolean valid = text.endsWith(text.substring(0, 2));
I'm assuming you already know the string is of length 2 or more... if not, you should check that first. (And change the variable valid to whatever makes sense in your context.)
This is a dynamic code for what you need to do
let's say we have
String testak = "tesHJKLtes"
//index you need to check here 2
int ind = 2;
ind is the index you need to check
if ( testak.substring(0,ind).equals(testak.substring(testak.length()
-ind-1,testak.length()-1))){
System.out.println("yeeaaahhh");
}
and consider that this you are not limited to 2 anymore you can give ind any number you like
and it will work