I know this error has been asked a lot. I have looked at them but still don't really understand how it applies to my problem. I am trying to write a program that creates a diamond pattern from a string.
public static String nameDiamond(String s) {
int len = s.length();
int i = 0;
String out = "";
while(i < len) {
out = out + s.substring(0, i + 1) + "\n";
i++;
}
while(i > 0) {
int numSpaces = len - i + 1;
for(int j = 0; j < numSpaces; j++)
out = out + " ";
out = out + s.substring(len - i + 1, i - 1) + "\n";
i--;
}
return out;
}
Now my understanding of substring is, that it is structured like s.substring(startIndex, endIndex) and a cause of this error can be when the end index is less then the start but I don't think this is the problem here. I also saw some causes of the error is when something does not exist but again I don't think this is the problem. What am I missing?
When it is tested with "Marty" it says -1 and with "Bill Nye" it says -2. Would the space be causing this?
I looked at lots of other versions of the questions but the ones that seemed relevent were:
StringIndexOutOfBoundsException: string index out of range
StringIndexOutOfBoundsException: String index out of range: -1
But I don't think they apply.
For reference, this is the problem:
https://www.codestepbystep.com/problem/view/java/strings/nameDiamond
Here is one you can use as an example. It doesn't do exactly what you want but it will illustrate one important thing. For fixed width fonts, each row must be an odd number of characters. Otherwise they won't line up properly.
If n is an even number, this particular version will print the same diamond for n and n+1. It is also limited by the string of spaces.
public static void printDiamond(int len) {
String str = "*";
String space = " ";
for (int i = 0; i < len/2 + 1; i++) {
System.out.print(space.substring(0,len/2-i));
System.out.println(str);
str = str+"**";
}
str = str.substring(2);
for(int i = 0; i < len/2; i++) {
str = str.substring(2);
System.out.print(space.substring(0,i+1));
System.out.println(str);
}
}
As you debug your program, use ubiquitous print statements to print the different variables such as indices and string lengths.
Related
This question already has answers here:
Splitting a string at every n-th character
(10 answers)
Closed 2 years ago.
Suppose I have a string: "VJKUKUTGCNNAUVWRKF"
How can I use loops to make it into this instead
"VJKUK UTGCN NAUVW RKF" where there is a space every
five characters (notice the last part only has three characters).
Perhaps
String str = "VJKUKUTGCNNAUVWRKF";
StringBuilder sb = new StringBuilder();
for (int j = 1; j <= str.length(); j++) {
sb.append(str.charAt(j-1));
if (j % 5 == 0) {
sb.append(" ");
}
}
String str2 = sb.toString();
I don't think it's a perfectly optimized solution, but it is one way.
If you are using java8 or higher :
String original = "VJKUKUTGCNNAUVWRKF";
String modifided = Pattern.compile("(?<=\\G.{5})")
.splitAsStream(original)
.collect(Collectors.joining(" "));
If you want to use regex please refer this
Splitting a string at every n-th character
Code:
String s = "VJKUKUTGCNNAUVWRKF";
System.out.println(java.util.Arrays.toString(s.split("(?<=\\G.....)")));
You can use some variables to keep track of the index positions and use substring(startIndex, endIndex) to update the new string. We use StringBuilder to create the new String.
String first = "VJKUKUTGCNNAUVWRKF";
StringBuilder splittedString = new StringBuilder();
int length = first.length();
int index = 0;
while(length > 0){
int endIndex = index + 5;
if(length <= 5){
endIndex = index + length;
}
splittedString.append(first.substring(index, endIndex));
splittedString.append(" ");
length -= 5;
index += 5;
}
System.out.println(splittedString.toString().trim());
Use String.substring() and concatenate.
String s = "JJGDVKJGFGKKGRFJJF";
String result="";
for (int i=0;i<s.length;i+=5) {
if(!result.equals("") result+=" ";
result+=s.substring(i, Math.max(i+5, s.length));
}
I'm writing from my mobile. So it's difficult to make a good code. There may be a few mistakes to correct.
#Aharon already give you a good solution, but it could produce redundant " " when the String length is a multiple of 5.
This could fix the case and be a little more efficient and organized:
public static String split(String s, int size, String sep) {
if (s.length() <= size) {
return s;
}
final int expectedLength = s.length() + s.length() / size;
final StringBuilder sb = new StringBuilder(expectedLength);
sb.append(s, 0, size);
int counter = 2 * size;
while (counter <= s.length()) {
sb.append(sep).append(s, counter - size, counter);
counter += size;
}
if (counter - size < s.length()) {
sb.append(sep).append(s, counter - size, s.length());
}
return sb.toString();
}
So you can just call:
String s = "VJKUKKASDD";
String out = split(s, 5, " ");
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am doing one simple java code where if
input is : "aabbba"
then
output should be: "a2b3a1"
I have done the below coding but missing somewhere. So let me know my mistake.
public class Test {
public static void main(String[] args) {
String str = "aabbba";
int count = 1;
for (int i = 0; i < str.length(); i = i + count) {
count = 1;
for (int j = i + 1; j < str.length(); j++) {
if (str.charAt(i) == str.charAt(j)) {
count = count + 1;
} else {
System.out.println(str.charAt(i) + "" + count);
break;
}
}//end of inner for
}//end of outer for
}//end of main
}//end of class
Actually you have too much code, You only need one loop, and you should be comparing the letter to the previous one, not attempting to compare each letter to every letter after it.
If you are confused about what your program is doing, the best place to start is to use your debugger to step through the code.
for(int i = 0, count = 1; i < str.length(); i++, count++) {
char ch = str.charAt(i);
char next = i + 1 < str.length() ? str.charAt(i + 1) : (char) -1;
if (ch != next) {
System.out.print("" + ch + count);
count = 0;
}
}
Using your effort and code, you simply did put the print to the wrong place
String str = "aabbba";
int count = 1;
for(int i = 0; i <str.length();i=i+count){
count =1;
for(int j = i+1; j<str.length();j++){
if(str.charAt(i) == str.charAt(j)){
count = count+1;
}
else{
break;
}
}
// Print here otherwise you will miss the last group of letters
// Also if you just want one line use .print instead of println
System.out.print(str.charAt(i)+""+count);
}
Using Java-8 and my StreamEx library it's a one-liner:
String input = "aabbba";
String result = IntStreamEx.ofChars(input).mapToObj(ch -> (char)ch)
.runLengths().join("").joining();
Step-by step:
IntStreamEx.ofChars(input): create IntStreamEx (enhanced IntStream) where each element is the corresponding character of input line.
.mapToObj(ch -> (char)ch): transform to StreamEx<Character> (enhanced Stream<Character>) where each element is the Character object.
.runLengths(): convert to EntryStream<Character, Long> (enhanced Stream<Map.Entry<Character, Long>>) where keys are Character objects and values are counts of equal adjacent characters.
.join(""): convert to StreamEx<String>, joining keys (characters) and values (counts) via given empty separator.
.joining(): final reduction to the resulting string without additional separators.
You're just missing the print of the last group of letters. you only print inside the loop once you found a different letter, you should take into account the last group of letters that has no "different letter" after it
I would suggest using a StringBuilder:
public String myOutput(String str) {
if (str == null || str.length() == 0)
return str;
StringBuilder sb = new StringBuilder();
int count = 1;
char currentChar;
for (int i = 0; i < str.length() - 1; i++) {
currentChar = str.charAt(i);
if (currentChar == str.charAt(i+1)) {
count++;
} else {
sb.append(currentChar);
sb.append(String.valueOf(count));
count = 1;
}
}
sb.append(str.charAt(str.length()-1));
sb.append(String.valueOf(count));
return sb.toString();
}
You only need 1 loop
System.out.println() will cause your output to have line break. You better use System.out.print(). Now your currrent code is resulting :
a2
b3
I'm currently working on a problem in code hunt level 6.02 which asks me to capitalize every other letter in a String. I have tried doing it with toCharArray + StringBuilder in for loops. It works, but it's not good enough. I still can't get the perfect score for the problem. I'm running out of ideas. Any help will be greatly appreciated.
Note: This is my first post on stack overflow. So if I miss anything or ask question in a wrong way. Pls feel free to point it out for me. Thx.
s is the input string
Attempt 1:
char [] words = s.toCharArray();
for (int i = 0; i < words.length; i +=2){
words[i] = Character.toUpperCase(words[i]);
}
return new String(words);
Attempt 2:
StringBuilder result = new StringBuilder(s);
for (int i = 0; i < result.length(); i +=2){
result.replace(i, i + 1, result.substring(i,i + 1).toUpperCase());
}
return result.toString();
Input: "iaiaa"
Expected output: "IaIaA"
In both of your attempts, you're going through the characters 2 1/2 times.
Taking your second attempt;
StringBuilder result = new StringBuilder(s);
for (int i = 0; i < result.length(); i +=2){
result.replace(i, i + 1, result.substring(i,i + 1).toUpperCase());
}
return result.toString();
The first line copies all the characters, and your last line copies all the characters. Your for loop goes through half the characters, for a total of 2 1/2 sets of characters.
I don't know if this is faster, but here's my attempt.
String r = "";
for (int i = 0; i < s.length; i++) {
if (i % 2 == 0) {
r += s.substring(i, i + 1).toUpperCase();
} else {
r += s.substring(i, i + 1);
}
}
return r;
I realize that this looks like a lot of intermediate Strings are created, but string concatenation has improved since Java 1.7.
I don't know how efficient this really is, but this does the trick for capitalizing the first letter and every other letter after.
String sentence = "i want to manipulate this string";
char[] array = new char[] {};
array = sentence.toCharArray(); //put the sentence into a character array
for (int i = 0; i < array.length; i += 2) {
if (array[i] == ' ') { //if the character is blank, move to the next index
i++;
}
array[i] = Character.toUpperCase(array[i]); //capitalize
}
sentence = new String(array); //revert array back to String
System.out.println(sentence); //display
Hello I am having trouble implementing this function
Function:
Decompress the String s. Character in the string is preceded by a number. The number tells you how many times to repeat the letter. return a new string.
"3d1v0m" becomes "dddv"
I realize my code is incorrect thus far. I am unsure on how to fix it.
My code thus far is :
int start = 0;
for(int j = 0; j < s.length(); j++){
if (s.isDigit(charAt(s.indexOf(j)) == true){
Integer.parseInt(s.substring(0, s.index(j))
Assuming the input is in correct format, the following can be a simple code using for loop. Of course this is not a stylish code and you may write more concise and functional style code using Commons Lang or Guava.
StringBuilder builder = new StringBuilder();
for (int i = 0; i < s.length(); i += 2) {
final int n = Character.getNumericValue(s.charAt(i));
for (int j = 0; j < n; j++) {
builder.append(s.charAt(i + 1));
}
}
System.out.println(builder.toString());
Here is a solution you may like to use that uses Regex:
String query = "3d1v0m";
StringBuilder result = new StringBuilder();
String[] digitsA = query.split("\\D+");
String[] letterA = query.split("[0-9]+");
for (int arrIndex = 0; arrIndex < digitsA.length; arrIndex++)
{
for (int count = 0; count < Integer.parseInt(digitsA[arrIndex]); count++)
{
result.append(letterA[arrIndex + 1]);
}
}
System.out.println(result);
Output
dddv
This solution is scalable to support more than 1 digit numbers and more than 1 letter patterns.
i.e.
Input
3vs1a10m
Output
vsvsvsammmmmmmmmm
Though Nami's answer is terse and good. I'm still adding my solution for variety, built as a static method, which does not use a nested For loop, instead, it uses a While loop. And, it requires that the input string has even number of characters and every odd positioned character in the compressed string is a number.
public static String decompress_string(String compressed_string)
{
String decompressed_string = "";
for(int i=0; i<compressed_string.length(); i = i+2) //Skip by 2 characters in the compressed string
{
if(compressed_string.substring(i, i+1).matches("\\d")) //Check for a number at odd positions
{
int reps = Integer.parseInt(compressed_string.substring(i, i+1)); //Take the first number
String character = compressed_string.substring(i+1, i+2); //Take the next character in sequence
int count = 1;
while(count<=reps)//check if at least one repetition is required
{
decompressed_string = decompressed_string + character; //append the character to end of string
count++;
};
}
else
{
//In case the first character of the code pair is not a number
//Or when the string has uneven number of characters
return("Incorrect compressed string!!");
}
}
return decompressed_string;
}
I'm doing a project for Java 1, and I'm completely stuck on this question.
Basically I need to double each letter in a string.
"abc" -> "aabbcc"
"uk" -> "uukk"
"t" -> "tt"
I need to do it in a while loop in what is considered "Java 1" worthy. So i'm guessing that this means more of a problematic approach.
I know that the easiest way for me to do this, from my knowledge, would be using the charAt method in a while loop, but for some reason my mind can't figure out how to return the characters to another method as a string.
Thanks
[EDIT] My Code (wrong, but maybe this will help)
int index = 0;
int length = str.length();
while (index < length) {
return str.charAt(index) + str.charAt(index);
index++;
}
String s="mystring".replaceAll(".", "$0$0");
The method String.replaceAll uses the regular expression syntax which is described in the documentation of the Pattern class, where we can learn that . matches “any character”. Within the replacement, $number refers to numbered “capturing group” whereas $0 is predefined as the entire match. So $0$0 refers to the matching character two times. As the name of the method suggests, it is performed for all matches, i.e. all characters.
Yeah, a for loop would really make more sense here, but if you need to use a while loop then it would look like this:
String s = "abc";
String result = "";
int i = 0;
while (i < s.length()){
char c = s.charAt(i);
result = result + c + c;
i++;
}
You can do:
public void doubleString(String input) {
String output = "";
for (char c : input.toCharArray()) {
output += c + c;
}
System.out.println(output);
}
Your intuition is very good. charAt(i) will return the character in the string at location i, yes?
You also said you wanted to use a loop. A for loop, traversing the length of the list, string.length(), will allow you to do this. At every single node in the string, what do you need to do? Double the character.
Let's take a look at your code:
int index = 0;
int length = str.length();
while (index < length) {
return str.charAt(index) + str.charAt(index); //return ends the method
index++;
}
Problematically for your code, you are returning two characters immediately upon entering the loop. So for a string abc, you are returning aa. Let's store the aa in memory instead, and then return the completed string like so:
int index = 0;
int length = str.length();
String newString = "";
while (index < length) {
newString += str.charAt(index) + str.charAt(index);
index++;
}
return newString;
This will add the character to newString, allowing you to return the entire completed string, as opposed to a single set of doubled characters.
By the way, this may be easier to do as a for loop, condensing and clarifying your code. My personal solution (for a Java 1 class) would look something like this:
String newString = "";
for (int i = 0; i < str.length(); i++){
newString += str.charAt(i) + str.charAt(i);
}
return newString;
Hope this helps.
try this
String a = "abcd";
char[] aa = new char[a.length() * 2];
for(int i = 0, j = 0; j< a.length(); i+=2, j++){
aa[i] = a.charAt(j);
aa[i+1]= a.charAt(j);
}
System.out.println(aa);
public static char[] doubleChars(final char[] input) {
final char[] output = new char[input.length * 2];
for (int i = 0; i < input.length; i++) {
output[i] = input[i];
output[i + 1] = input[i];
}
return output;
}
Assuming this is inside a method, you should understand that you can only return once from a method. After encountering a return statement, the control goes back to the calling method. Thus your approach of returning char every time in a loop is faulty.
int index = 0;
int length = str.length();
while (index < length) {
return str.charAt(index) + str.charAt(index); // only the first return is reachable,other are not executed
index++;
}
Change your method to build a String and return it
public String modify(String str)
{
int index = 0;
int length = str.length();
String result="";
while (index < length) {
result += str.charAt[index]+str.charAt[index];
index++;
}
return result;
}