Reputation: 69
I have to make a text file in which I'm supposed to put 100 random characters where on each even position should be a small letter and on each odd position should be a capital letter. Also, all the letters are supposed to be separated by a blank field (space). I only succeeded to make a 100 random characters list but I don't know how to do the rest.
public class Main {
public static char getRandomCharacter(char c1, char c2) {
return (char) (c1 + Math.random() * (c2 - c1 + 1));
}
public static char[] createArray() {
char[] character = new char[100];
for (int i = 0; i < character.length; i++) {
character[i] = getRandomCharacter('a', 'z');
}
for (int i = 0; i < character.length; i++) {
System.out.println(character[i]);
}
return character;
}
public static void main(String[] args) {
createArray();
}
}
I would appreciate the help.
EDIT: Here's an edited version. However, the output is not much different b j r m r b k i...
public class Main {
public static char getRandomCharacter(char c1, char c2) {
return (char) (c1 + Math.random() * (c2 - c1 + 1));
}
public static char[] createArray() {
char[] character = new char[100];
for (int i = 0; i < character.length; i++) {
character[i] = getRandomCharacter('a', 'z');
}
for (int i = 0; i < character.length; i++) {
System.out.println(character[i]);
}
return character;
}
public static void main(String[] args) {
char[] arr = createArray();
StringBuilder text = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
int pos = i + 1;
if (pos % 2 != 0) {
String s = "" + arr[i];
text.append(s.toUpperCase());
} else {
text.append(arr[i] + " ");
}
}
String content = text.toString().trim();
}
}
Upvotes: 2
Views: 853
Reputation: 338775
The Answer by WJS looks correct. But, unfortunately, the char
type is legacy. As a 16-bit value, the char
type is physically incapable of representing most characters. So I recommend making a habit of using code point integer numbers instead of char
.
IntSupplier
for IntStream
of code pointsAlso, I happened to notice the method IntStream.generate
that takes an IntSupplier
. We can write our own implementation of that interface IntSupplier
that alternates between returning a code point number for an uppercase letter and returning a code point for a lowercase letter.
Within our implementation we define an enum of two objects, to represent uppercase and lowercase.
Our implementation has a constructor taking either of those two enum objects. The passed argument signals the case of the first letter to be generated.
package work.basil.example.rando;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.IntSupplier;
public class SupplierOfCodePointForBasicLatinLetterInAlternatingCase
implements IntSupplier
{
public enum LetterCase { UPPERCASE, LOWERCASE }
private LetterCase currentCase;
public SupplierOfCodePointForBasicLatinLetterInAlternatingCase ( final LetterCase startingCase )
{
this.currentCase = startingCase;
}
@Override
public int getAsInt ( )
{
int codePoint =
switch ( this.currentCase )
{
case UPPERCASE -> ThreadLocalRandom.current().nextInt( 65 , 91 ); // ( inclusive , exclusive )
case LOWERCASE -> ThreadLocalRandom.current().nextInt( 97 , 123 );
};
this.currentCase =
switch ( this.currentCase )
{
case UPPERCASE -> LetterCase.LOWERCASE;
case LOWERCASE -> LetterCase.UPPERCASE;
};
return codePoint;
}
}
When we invoke our customized IntStream
, we pass a limit of the number of code points to generate.
Finally, we collect all the generate code points into a StringBuilder
from which we build our final resulting String
object.
IntStream streamOfCodePoints = IntStream.generate( new SupplierOfCodePointForBasicLatinLetterInAlternatingCase( SupplierOfCodePointForBasicLatinLetterInAlternatingCase.LetterCase.UPPERCASE ) );
String result =
streamOfCodePoints
.limit( 100 )
.collect( StringBuilder :: new , StringBuilder :: appendCodePoint , StringBuilder :: append )
.toString();
ZtAxIqWfEhOeHdSgOpMyPuJwLuSwJqHzUwSlLeQnFoFcAaMfOxMiBnVuZxOpCvPuLiZhBmIrGaBqZzIyOoUhAdFmXgArVwWqBoWr
Your requirements specify that each generated letter be separated by a space.
Somewhere define a constant for the code point of 32 for the SPACE character.
private static final int SPACE = 32; // ASCII & Unicode code point for SPACE character is 32 decimal.
Then alter our .collect
line to use expanded syntax. Instead of a method reference, we use a lambda. In that lambda, we call StringBuilder#appendCodePoint
twice. In the first call we append the generate code point. In the second call we append the SPACE character’s code point.
To eliminate the SPACE at the very end, we trim.
IntStream streamOfCodePoints = IntStream.generate( new SupplierOfCodePointForBasicLatinLetterInAlternatingCase( SupplierOfCodePointForBasicLatinLetterInAlternatingCase.LetterCase.UPPERCASE ) );
String result =
streamOfCodePoints
.limit( 100 )
.collect(
StringBuilder :: new ,
( stringBuilder , codePoint ) -> stringBuilder.appendCodePoint( codePoint ).appendCodePoint( App.SPACE ) ,
StringBuilder :: append
)
.toString()
.trim() ;
X t D j J g J m Y c J a E e H m U c H b U a R t J g R n G r V s P e B z D k G f H e Z r W t U l U f C z R j F z G k Z f A y I z N i L g Q y Q w D w D w P s F y E n J n I i R b B u H x U m B g K w C k
If you want to keep the SPACE on the end, drop the call to String#trim
.
Upvotes: 2
Reputation: 40044
Here is an alternative approach using Streams of ASCII characters. In the ASCII table, a-z
are adjacent as are A-Z
. So for any value d
from 0 to 25
, (char)(d + 'a')
will be a lower case letter and (char)(d + 'A') will be an upper case letter.
Random
instance.0 to 100
for 100
characters.i
and add either 'a' or 'A' to the value d
Random r = new Random();
String str = IntStream.range(0,100).mapToObj(
i -> {
int d = r.nextInt(26);
return String.valueOf((char)(i % 2 == 0 ? d + 'a' : d + 'A'));
}).collect(Collectors.joining(" "));
System.out.println(str);
prints something similar to
j H o C y X h H k A y F z J b D x A z R t Y w O d A a F q F t R n A i B k Y g F
y X c O r I h E k K t R n L a S d C s T m S z Y z H a V y N o R t S y I t E l W
q X l E v S h D r C y N h O o C l D u X
To write to a file, use try with resources
and also catch IO errors.
String file = "f:/myOutputFile.txt";
try (FileWriter output = new FileWriter(new File(file))) {
output.write(str);
} catch (IOException ioe) {
ioe.printStackTrace();
}
Here is how you could do it with a simple loop.
StringBuilder
to the a lower case letter for the 0th location which is even. This also allows prepending the space to avoid a trailing space at the end.1 to 100
to get the other 99
characters.StringBuilder
as a string as shown above.StringBuilder sb =
new StringBuilder().append((char) (r.nextInt(26) + 'a'));
for (int i = 1; i < 100; i++) {
int d = r.nextInt(26);
sb.append(" ")
.append((char) (i % 2 == 0 ? d + 'a' : d + 'A'));
}
Upvotes: 1
Reputation: 1368
In your case it's easier to create a string
first and then put it into a txt
file.
You can simply iterate through the random array and check for odd/even positions.
Use Character.toUpperCase
or Character.toLowercase
in respective odd even postion and append to the string.
Use StringBuilder
so that you don't have to create new String objects every time.
char[] arr = createArray();
StringBuilder text = new StringBuilder();
//iterate thoruh the arr
for (int i = 0; i < arr.length; i++) {
int pos = i+1;
if(pos%2!=0){ // check whether current postion is odd or even
text.append(Character.toUpperCase(arr[i])+" ");// if position is odd then convert it to uppercase
}else{
text.append(arr[i]+" "); // if position is even then convert it toLowercase if needed (if arr contents both upper case and lower case)
}
}
String content = text.toString().trim(); // trimin to remove any extra space in last or first of the string.
To write in file
String path = "D:/a.txt";
Files.write( Paths.get(path), content.getBytes());
EDIT 1 :
I am not sure why this Character.toUpperCase
is not working. You can try this below conversion, the drawback is that a String
object will be created for every even position.
String s = ""+ arr[i];
text.append(s.toUpperCase()+" ");
EDIT 2: You can use normal String
String text = "";
for (int i = 0; i < arr.length; i++) {
int pos = i + 1;
if (pos % 2 != 0) {
String s = "" + arr[i];
text =text + s.toUpperCase()+" ";
} else {
text= text + (arr[i] + " ");
}
}
String content = text.toString().trim();
System.out.println(content);
Upvotes: 0