This question already has answers here:
String's Maximum length in Java - calling length() method
(7 answers)
Closed 9 years ago.
these's something strangly i found that is when String length in java exceeding a value, then it shown odd.
there is my test code
public static void main(String[] args) {
int length = 4096;
char[] chars = new char[length];
for (char c : chars) {
c = 'c';
}
String str = new String(chars);
System.out.println(str.length());
System.out.println(str);
}
when i run above code on my computer, i get 4096 space character output from console.
then i change the length variable to 4095, this time output is correct, 4095 c character.
but on another computer, the output does not correct unless the length variable less than 2900.
i just can't figure out why?
EDIT
i think i figured out what's going on, i try to run it again in command window, even though the length value is big enough , it's print correct.
so it seemed like some limit about eclipse's console.
but i checked my eclipse console buffer size, its 800000
You are only changing the value of the local variable c and not the values of the entries in the char[].
To change the actual values, use a "regular" for loop, and not a for-reach loop:
for (int i = 0; i < chars.length; i++) {
chars[i] = 'c';
}
As a side note, a String in java is NOT a char[] - it's a String object.
Related
This question already has answers here:
Using Regex to generate Strings rather than match them
(12 answers)
Closed 9 months ago.
This post was edited and submitted for review 9 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I am trying to write a program that would ask the user how many security codes he wants to generate, then it would output as many codes as he requested in an array.
The security code should be 7 characters long and have the following format: NNNNLLL, where N is a random number and L is a random upper case letter.
The method should create security codes with the above format by randomly selecting the characters, i.e. numbers and letters.
I am expecting the program to output something like this if a user selects to generate 4 codes:
“2394QAB”
“2821TSZ”
“7173AAY”
“2236WQA”
I can only use the methods for this code learned in my course and I cannot use other libraries like regex, that is why I am trying it like this.
This is the code I have done so far:
import java.util.Random;
public class ItemChecker{
private StringBuffer strBuff;
private String[] codes;
private String CodeLetters, CodeNumbers;
private int[] RandomNums;
public ItemChecker(){
strBuff=new StringBuffer();
}
public String[] getCodes(int[] amount){
codes=new String[amount.length];
for(int i=0;i<amount.length;i++)
{
CodeLetters="";
strBuff=new StringBuffer();
for(int j=0;j<4;j++)
{
Random RandomNumber=new Random();
int randomIndex=RandomNumber.nextInt(RandomNums.length);
CodeNumbers.append(RandomNumber[randomIndex]);
}
for(int j=0;j<3;j++)
{
Random RandomLetter=new Random();
char c =(char)(RandomLetter.nextInt(26)+'a');
CodeLetters+=c;
}
codes[i]=CodeNumbers+CodeLetters;
}
}
}
My intention is to create 4 random digits and 3 random letters and add them together in a string to make the code. However, the code doesn't generate the random codes and I have no clue how to proceed from here.
Within your getCodes method there are a couple of mistakes. A StringBuiler would be more appropriate for this task, instead of using a StringBuffer or chaining strings with the + operator. As a matter of fact, each time you're performing a concatenation with the + operator you're creating a new string in memory, rather than working on a same instance, this is not that efficient. Also, when you're adding an offset to the random value representing an upper case letter, you're adding the lower case 'a', instead of the upper case 'A'.
In your program, you could define a static method to offer the code generation service as a general utility and then invoke it within your getCodes method.
In the utility method, you could declare a Random object to get random int values. Then, with a first for loop, you could generate random values between 0 included and 10 excluded, and append them to a StringBuilder object. The String class represents immutable objects, so you need to use a StringBuilder to build one. As said above, chaining strings with the + operator will create new instances at each concatenation, you're not working on the same object.
Then, with a second for loop you could generate random values from 0 to 27 excluded, add to every value the offset 65, representing the upper case 'A' letter (lower case 'a' has value 97), and then cast this int value to a char to get its character representation. Finally, append the char to your StringBuilder instance.
Here is an implementation:
public class Main {
public static void main(String[] args) {
System.out.println(getSecurityCode());
}
public String[] getCodes(int[] amount) {
String[] codes = new String[amount.length];
for (int i = 0; i < codes.length; i++) {
codes[i] = getSecurityCode();
}
return codes;
}
public static String getSecurityCode() {
Random rand = new Random();
StringBuilder strBuilder = new StringBuilder();
//Appending 4 random digits
for (int i = 0; i < 4; i++) {
//nextInt(10) returns a value between 0 (included) and 10 (excluded)
strBuilder.append(rand.nextInt(10));
}
//Appending 3 random upper case letters
for (int i = 0; i < 3; i++) {
//rand.nextInt(27) returns a random value between 0 and 26 included to represent an alphabet letter.
//This value is added with the offset 65 which represents the upper case A letter.
//Finally, this value is cast as a char or else it would append its int value
strBuilder.append((char)(65 + rand.nextInt(27)));
}
return strBuilder.toString();
}
}
To simplify your code that generate the password you could use RandomStringUtils from org.apache.commons.lang3.RandomStringUtils like described in this great tutorial https://www.baeldung.com/java-random-string.
You just have to generate 2 strings :
One with 4 digits
One with 3 letters to uppercase
And concat both.
Here's How
public static String getSecurityCode() {
//generate 4 numbers only
String generatedNumbers = RandomStringUtils.random(4, false, true);
//generate 3 letters only
String generatedLetters = RandomStringUtils.random(3, true, false).toUpperCase();
return generatedNumbers + generatedLetters;
}
Or with StringBuilder
public static String getSecurityCode2() {
StringBuilder stb=new StringBuilder(7);
//generate 4 numbers only
stb.append(RandomStringUtils.random(4, false, true));
//generate 3 letters only
stb.append( RandomStringUtils.random(3, true, false).toUpperCase());
return stb.toString();
}
Another way of doing this is to utilize StringBuilder's appendCodePoint method for this:
int number= random.nextInt(10000); //generate any number between 0 to 9999
StringBuilder builder=new StringBuilder();
for(int i=0;i<3;i++) {
builder.appendCodePoint(65+random.nextInt(26));
}
String result=number+builder.toString();
System.out.println(result);
How to delete the characters at x and keep the rest? The output should be "12345678" Deleting every '9' in the position that x is on. X is i*(i+1)/2 so that the number is added to the next number. So every number at 0,1,3,6,10,15,21,28,etc.
public class removeMysteryI {
public static String removeMysteryI(String str) {
String newString = "";
int x=0;
for(int i=0;i<str.length();i++){
int y = (i*(i+1)/2)+1;
if(y<=str.length()){
x=i*(i+1)/2;
newString=str.substring(0, x) + str.substring(x + 1);
}
}
return newString;
}
public static void main(String[] args) {
String str = "9919239456978";
System.out.println(removeMysteryI(str));
}
}
OK, so there are a couple of mistakes in your code. One is easy to fix. The others not so easy.
The easy one first:
newString=str.substring(0, x) + str.substring(x + 1);
OK so that is creating a string with the character at position x removed. The problem is what it is operating on. The str variable is the input parameter. So at the end of the day newString will still only be str with one character removed.
The above actually needs to be operating on the string from the previous loop iterations ... if you are going to remove more than one character.
The next problem arises when you try to solve the first one. When you remove a character from a string, all characters after the removal point are renumbered; e.g. after removing the character at 5, the character at 6 becomes the character at 5, the character at 7 becomes the character at 6, and so on.
So if you are going to remove characters by "snipping" the string, you need to make sure that the indexes for the positions for the "snips" are adjusted for the number of characters you have already removed.
That can be done ... but you need to think about it.
The final problem is efficiency. Each time your current code removes a single character (as above), it is actually copying all remaining characters to a new string. For small strings, that's OK. For really large strings, the repeated copying could have a serious performance impact1.
The solution to this is to use a different approach to removing the characters. Instead of snipping out the characters you want to discard, copy the characters that you want to keep. The StringBuilder class is one way of doing this2. If you are not permitted to use that, then you could do it with an array of char, and an index variable to keep track of your "append" position in the array. Finally, there is a String constructor that can create a String from the relevant part of the char[].
I'll leave it to you to work out the details.
1 - Efficiency could be viewed as beyond the scope of this exercise.
2 - #Horse's answer uses a StringBuilder but in a different way to what I am suggesting. This will also suffer from the repeated copying problem because each deleteCharAt call will copy all characters after the deletion point.
Follow the steps below:
Initialize with builderIndexToDelete = 0
Initialize with counter = 1
Repeat the following till the index is valid:
delete character at builderIndexToDelete
update builderIndexToDelete to counter - 1 (-1 as a character is deleted in every iteration)
increment the counter
public static String deleteNaturalSumIndexes(String str) {
StringBuilder builder = new StringBuilder(str);
int counter = 1;
int builderIndexToDelete = 0;
while (builderIndexToDelete < builder.length()) {
builder.deleteCharAt(builderIndexToDelete);
builderIndexToDelete += (counter - 1);
counter++;
}
return builder.toString();
}
public static void main(String[] args) {
String str = "9919239456978";
System.out.println(deleteNaturalSumIndexes(str));
}
Thank you #dreamcrash and #StephenC
Using #StephenC suggestion to improve performance
public static String deleteNaturalSumIndexes(String str) {
StringBuilder builder = new StringBuilder();
int nextNum = 1;
int indexToDelete = 0;
while (indexToDelete < str.length()) {
// check whether this is a valid range to continue
// handles 0,1 specifically
if (indexToDelete + 1 < indexToDelete + nextNum) {
// min is used to limit the index of last iteration
builder.append(str, indexToDelete + 1, Math.min(indexToDelete + nextNum, str.length()));
}
indexToDelete += nextNum;
nextNum++;
}
return builder.toString();
}
public static void main(String[] args) {
System.out.println(deleteNaturalSumIndexes(""));
System.out.println(deleteNaturalSumIndexes("a"));
System.out.println(deleteNaturalSumIndexes("ab"));
System.out.println(deleteNaturalSumIndexes("abc"));
System.out.println(deleteNaturalSumIndexes("99192394569"));
System.out.println(deleteNaturalSumIndexes("9919239456978"));
}
This question already has answers here:
Java: parse int value from a char
(9 answers)
How can I convert a char to int in Java? [duplicate]
(4 answers)
Closed 2 years ago.
I have this problem where I need to create a method that takes in a String and creates an integer array of each character. I have checked each step of the for loop and the array before and after the loop, and I am lost.
It correctly shows each character as '3' '4' and '5', however once it is inserted into the array, it always prints [51, 52, 53]. I am so lost where those numbers even came from? Thanks so much...
public class CodingBat {
public static void main(String[] args) {
String text = "345";
int[] create = new int[text.length()];
for(int i = 0; i < text.length(); i++) {
System.out.printf("Current array: %s\n", Arrays.toString(create));
//System.out.println(text.charAt(i));
create[i] = text.charAt(i);
System.out.printf("Adding %c\n", text.charAt(i));
}
System.out.println(Arrays.toString(create));
}
}
You're inserting a char into a int array, if i remember, the numbers that you see printing the array are the ASCII code.
So, if you want to get the number, use:
create[i] = Character.getNumericValue(text.charAt(i))
Chandu is a bad student. Once his teacher asked him to print the reverse of a given string. He took three hours to solve it. The teacher got agitated at Chandu and asked you the same question. Can you solve it?
Input
The first line contains an integer T, denoting the number of test cases.
Each test case contains a string S, comprising of only lower case letters.
Output
For each test case, print the reverse of the string S.
Constraints
1 <= T <= 10
1 <= |S| <= 30
Input Sample Output(Plaintext Link)
2
ab ba
aba aba
Time Limit
1 sec(s) for each input file.
Memory Limit
256 MB
Source Limit
1024 KB
MyApproach1
MyApproach2
To reverse a string I used XOR logic to reverse the string.
#Edit
public static void main(String args[] ) throws Exception
{
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
for (int i = 1; i <= T; ++i)
{
String input = sc.next();
int len = input.length();
StringBuilder input1 = new StringBuilder(len);
int end = input.length()-1;
int start = 0;
while (start<end)
{
input1.setCharAt(start,input.charAt(start)^input.charAt(end));
input1.setCharAt(end,input.charAt(end)^input.charAt(start));
input1.setCharAt(start,input.charAt(start)^input.charAt(end));
++start;
--end;
}
System.out.println(input1.toString());
}
}
I am still getting the following error.
How do I correct this?
For approach 1, all you need to do is remove the call to sc.nextLine() and everything will be fine. That's because each line contains a "token" i.e. a word, delimited by whitespace. That's what sc.next() will return. No need to call nextLine() after that.
For your approach 2, you should carefully read the API documentation of StringBuilder. This shows you how to create a String from a StringBuilder, and vice versa. (Whenever I write Java code, I have a browser window with the API documentation for quick reference next to my editor window. It's very useful.)
Edit (after the latest edit to the question):
There is a compilation problem and a runtime problem. First, the XOR operator produces a result of type int, even if its operands are char. So you should put your expression in parentheses and cast it to char. Once you've done that, you'll get a runtime error because you are trying to index an element of a StringBuilder which does not yet exist. When you created the StringBuilder like this:
StringBuilder input1=new StringBuilder(len);
len is the initial capacity. The value of the StringBuilder instance is initially "". You then call setCharAt() but the current size of the StringBuilder is 0, so you get an index-out-of-bounds exception. You need to initialise the StringBuilder with the string itself:
StringBuilder input1=new StringBuilder(input);
Now you won't get an exception, but you'll get the wrong answer. That's because of a problem with your XOR logic.
After
sc.nextInt();
write
sc.nextLine();
before starting first loop.
For the two lines of your code
String s1 = sc.next();
sc.nextLine();
write just
String s1 = sc.nextLine();
The next() function gives you characters before a space while next line gives you whole line.
It'll work Fine.
I am trying to take a file full of strings, read it, then print out a few things:
The string
The string backwards AND uppercase
The string length
There are a few more things, however I haven't even gotten to that point and do not want to ask anyone to write the code entirely for me. After messing around with it for a while, I have it almost completed (I believe, save for a few areas).
The piece that is tripping me up is the backwards word. We are required to put our output neatly into columns using prinf, but I cannot do this if I read each char at a time. So I tried setting a String backwardsWord = ""; and adding each character.
This is the piece that is tripping me up:
for(int i = upperCaseWord.length() - 1; i >= 0; i--)
{
backwardsWord += (upperCaseWord.charAt(i) + "");
}
My issue is that when I print it, the first word works properly. However, each word after that is added to the previous word.
For example: if I am printing cat, dog, and rat backwards, it shows
TAC
TACGOD
TACGODTAR
I obviously want it to read
TAC
GOD
TAR
Any help would be appreciated.
It looks like your variable backwardsWord is always appending a character without being reset between words. The simplest fix is to clear the backwardsWord just before your loop by setting it to empty string.
backwardsWord = ""; //Clear any existing characters from backwardsWord
for(int i = upperCaseWord.length() - 1; i >= 0; i--)
{
backwardsWord += (upperCaseWord.charAt(i) + "");
}
If you are building up a String one character at a time you will be using a lot of memory because Java Strings are immutable.
To do this more efficiently use a StringBuilder instead. This is made for building up characters like what you are doing. Once you have finished you can use the toString method to get the String out.
StringBuilder builder = new StringBuilder(); //Creates the String builder for storing the characters
for(int i = upperCaseWord.length() - 1; i >= 0; i--)
{
builder.append(upperCaseWord.charAt(i)); //Append the characters one at a time
}
backwardsWord = builder.toString(); //Store the finished string in your existing variable
This has the added benefit of resetting the backwardsWord each time.
Finally, since your goal is to get the String in reverse we can actually do it without a loop at all as shown in this answer
backwardsWord = new StringBuilder(upperCaseWord).reverse().toString()
This creates a new StringBuilder with the characters from upperCaseWord, reverses the characters then stores the final string in backwardsWord
Where are you declaring the String backwardsWord?
If you don't clear it between words then the memory space allocated to that string will still contain the previously added characters.
Make sure you are tossing in a backwardsWord = ""; in between words to reset it's value and that should fix your problem.
Without seeing more of your code I can't tell you exactly where to put it.
This should do the job ->
class ReverseWordsInString{
public static String reverse(String s1){
int l = s1.length();
if (l>1)
return(s1.substring(l-1) + reverse(s1.substring(0,l-1)));
else
return(s1.substring(0));
}
public static void main(String[] args){
String st = "Cat Dog Rat";
String r = "";
for (String word : st.split(" "))
r += " "+ reverse(word.toUpperCase());
System.out.println("Reversed words in the given string: "+r.trim());
}
}