How to print a random character from a string? - java

I have an assignment due and the last part of the assignment asks:
Suppose s is any string. Write a sequence of statements that will print a random character from s.
Here is what I have come up with so far:
for(int j = 0; j < s.length(); j++){
}
int l = ((int)Math.random()*s.length());
char ch = s.charAt(l);
System.out.println(ch);
I think these are the basic concepts I need to learn how to understand/use to write this code successfully. What I am confused on is where these specific lines of code go, for example if the charAt method should come before the loop, etc.

You almost had it already. I think your main issue was this part:
int l = ((int)Math.random()*s.length());
Your (int) cast is misplaced. If you read the javadoc of Math.random() you see that it returns a double value "greater than or equal to 0.0 and less than 1.0". Casting values of this range to int (i.e. simply cutting off all decimal places) will always result in 0, which only prints the first character of the string.
The solution is to first multiply it with the string's length and do the cast afterwards:
int l = (int)(Math.random()*s.length());
If you only want to print one random character, you don't need a loop of any sort, so you can delete that from your code.
See this fiddle for a working example. What you still need to do is think about how to get the input string (hint: maybe read it from System.in).
public static void main (String[] args) throws java.lang.Exception
{
String s = "foobar42";
int l = (int)(Math.random()*s.length());
char ch = s.charAt(l);
System.out.println(ch);
}
And to finally show off in class, you could also have a look at the Random class which could replace the above line with something like
int l = new Random().nextInt(s.length());
and see if you can grasp the difference between those two approaches. Although that is completely irrelevant to your assignment and way out of scope.

You can get a random character by using s.charAt(x), where x is a random number between 0 and the length of the String-1.
The code for this is as follows:
String s = "text string";
Random rand = new Random();
int randomIndex = rand.nextInt(s.length());//returns a random number between 0 and the index of the last character of the string
System.out.println(s.charAt(randomIndex));
When you need to do this several times, you just put it in a loop like this:
String s = "text string";
for(int i = 0; i < 10; i++) { //prints 10 random characters from the String
Random rand = new Random();
int randomIndex = rand.nextInt(s.length());//returns a random number between 0 and the index of the last character of the string
System.out.println(s.charAt(randomIndex));
}

Try this approach:
String s = "hello world";
System.out.println(Character.toString(s.charAt((new Random()).nextInt(s.length()))));
the s.length() returns the size of s;
the (new Random()).nextInt returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive);
the s.charAt returns the character at the position specified
the Character.toString returns the string representation of the specified character

I would do it like this:
System.out.println(s.charAt((int)(Math.random() * s.length())));

Related

It works if use 'int' but fails when I use 'long' . How do I make this function return long

the function only returns value when I declare 'n' as int, but returns null when i use 'long'.
Given a string and a value n, the string should be concatenated n number of times. in the concatenated string, we will take the first n characters in that string and return the number of letter 'a' that appeared.
Print a single integer denoting the number of letter a's in the first n letters of the infinite string created by repeating s infinitely many times.
In this function, two parameters are passed, a string and a long value. The code works very well if use an int value instead of long. Please how do i fix this long and int issue ?
public class StringLettersRepeat {
static long repeatedString(String s, long n) {
String string = "";
int count =0;
for(int i=0; i<n; i++){
string+=s;
}
char[] strChar = string.toCharArray();
char[] result = new char[(int) n];
for(int i=0; i<strChar.length;i++){
result[i]=strChar[i];
}
for(char str : result){
if('a'==str){
count++;
}
}
return count;
}
public static void main(String[] args) {
long result = repeatedString("a", 1000l);
System.out.println(result);
}
}
I expect the output to return a value, which is the number of count.
for example, if I enter string "aba" and n=7, it should return 5.
But if i pass in a string, say 'a' with n=100000000000, it's supposed to return 100000000000 but it doesn't work. Please what's possibly wrong with my code?
Given your example of calling repeatedString("aba", 7), the resulting string would be "abaabaa", and has 5 a's, as you said.
But, you don't actually have to build that result string. Instead, realize that the result string is the original string repeated 2 times, plus the first 1 characters of the string, both of which can easily be calculated using division and remainder math:
long repeats = n / s.length();
long extra = n % s.length();
Now, if you count the number of a's in the string, you can multiply by repeats. You don't need to repeat the counting operation. If you then also count the number of a's in the first extra characters of string, you have your final result.
int countFull = 0, countExtra = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == 'a') {
countFull++;
if (i < extra)
countExtra++;
}
}
Then calculate the total and return it:
return countFull * repeats + countExtra;
This code also runs a lot faster, because you only have to iterate s once, it doesn't matter for performance what n is, and you don't copy any characters, so it also uses a lot less memory. It actually doesn't use any memory.
Big-O is:
Performance: O(m) where m is length of input string.
Memory: O(1)
Neither is related to n.
Test
System.out.println(repeatedString("aba", 7));
System.out.println(repeatedString("a", 100000000000L));
Output
5
100000000000

Optimizing adding zero padding in a number

I'm practicing on how to optimize codes so any suggestion would be much appreciated. I have this method that adds zero padding to a number when its being incremented. The code are as follows:
public class CommonAlgorithm {
NumberRetrieve retrieve;
public long incrementNumber(CommonNumber t) {
CommonNumberFacade facade = new CommonNumberFacade(retrieve.apply(t));
String number = facade.getGeneratedNumber();
Long num = Long.parseLong(number);
num++;
String result = "";
if (String.valueOf(num).length() < number.length()) {
int length = number.length() - String.valueOf(num).length();
String zero = "";
for (int i = 0; i < length; i++) {
zero += "0";
}
result = zero + num;
} else {
result = String.valueOf(num);
}
return Long.parseLong(t.getPrefix()+result);
}
}
Are there more ways to optimize the code above?
Just in case anyone asks for the purpose of the function, the premise goes like this:
The function returns a number that is composed of the following: a 'prefix' and a 'number'. These two are concatenated to each other after the number has been incremented by 1. However, I realized that if the value of the number has zero padding in it, those zeroes will be disappear once they are converted into a long data type. Therefore if the following values are applied:
prefix = 123
number = 000001
The return value will be 1232 instead of 123000002. That is the problem that the function above is solving. I can't change the return type of the facade.generatedNumber() function into long as I need to return that String return type somewhere in my project eventually. I hope you could give a couple of suggestions
You can simplify your if-else statement as follows:
StringBuilder sb = new StringBulder();
String numStr = String.valueOf(num);
for (int i = numStr.length(); i < number.length(); i++) {
sb.append('0');
}
sb.append(numStr);
String result = sb.toString();
A few simple things:
You use String objects to build your results, like zero and result. Those could be StringBuilder objects. That would clearly express your intent to build strings!
You could look into using String.format()
You are invoking String.valueOf(num); three times, for the same num. You could do that once initially, and reuse that value, instead of computing it repeatedly.
Use the numerical primitive type long instead of the Object wrapper Long.
long num = Long.parseLong(number);
num++;
Place the string representation of num in its own variable.
String numStr = String.valueOf(num);
Zero padding to keep the number of original digits is only needed for increments for negative numbers, and then only for carries / digits '0'. This means that the zeroes should go after the sign.
String +, += is costly, use a StringBuilder:
StringBuilder sb = new StringBuilder(number.length());
Optimal is a relative, it would be okay to do:
long num = Long.parseLong(number);
++num;
String paddedNumStr = numStr.length >= number.length() ? numStr
: String.format("%" + number.length() + "d", num);
Using an if-expression as heuristic optimisation for 95% of the cases.

Trying to figure out how many times a certain set of characters appears in a bigger one with copying Arrays. Getting an error + is this the best way?

I want to write a program that figures out how many times a certain set of characters repeats itself in a longer set of characters (several times for several different set of characters)
I tried to achieve this by "importing" the long set of characters into a char array, and then make a 2D array for all the shorter sets of characters that I want to check the occurence of.
Then, I wanted my for loop to create an "interim" array of the same length as the short arrays have and compare it to each of them, however, the program keeps returning 0 occurences no matte what... And is also taking too long to compute when checking longer arrays with loads of character sets.
import java.util.*;
public class A {
public static void main (String [] args) {
Scanner sc = new Scanner (System.in);
//Preberi podatke
int dolzinaDolgi = sc.nextInt(); //D
int dolzinaKratki = sc.nextInt(); //d
int stKratkih = sc.nextInt(); //n
sc.nextLine(); // prehod v novo vrstico
char [] Dolgi = sc.nextLine().toCharArray(); //prebrano dolgo zaporedje
char [][] TabelaKratki = new char [stKratkih][dolzinaKratki];
int [] results = new int [stKratkih];
for (int i=0; i<stKratkih; i++) {
TabelaKratki[i]=sc.nextLine().toCharArray();
}
for (int i=0; i<dolzinaDolgi-dolzinaKratki; i++) {
char [] vmesnoZaporedje = new char [dolzinaKratki];
vmesnoZaporedje = Arrays.copyOfRange (Dolgi, 0+i, dolzinaKratki+i-1);
for (int j=0; j<stKratkih; j++) {
if (TabelaKratki [j] == vmesnoZaporedje) {
results [j] += 1;
}
}
}
for (int index = 0; index<stKratkih; index++) {
System.out.println(results[index]);
}
}
}
Perhaps regular expression is much better.
1. Convert the text to be searched into a pattern.
2. Store all different sets of characters into array.
3. Loop the array and loop to find occurrences using the pattern.
Refer to this answer for count the occurrences. java regex match count

Counting Significant Figures java

I am trying to make a program that counts significant figures and I am almost done there is one last thing that I am completely stuck on I can't figure out how to count the zeros between the non zero numbers here is my code:
public class Main {
public static void main(String[] args) {
String Integer = "10010000000";
String Substring = null;
String SubString2 = null;
if(Integer.contains(".")){
Substring = Integer.substring(0,Integer.indexOf("."));
System.out.println(Substring);
SubString2 = Integer.substring(Integer.indexOf(".")+1,Integer.length());
System.out.println(SubString2);
}
char [] array = Integer.toCharArray();
char [] array1 = null;
if(Substring !=null)
array1 = Substring.toCharArray();
char [] array2 = null;
if(SubString2!=null)
array2 = SubString2.toCharArray();
System.out.println(amountofSigFigs(array,array1,array2,Integer));
}
public static int amountofSigFigs(char [] a,char [] a1,char [] a2,String Integer){
int count = 0;
if(a1==null && a2 == null){
for(int i = 0;i<a.length;i++){
if(!(a[i]=='0')){
count++;
}
}
}
else{
for(int i = 0;i<a1.length;i++){
if(!(a[i]=='0')){
count++;
}
}
for(int i = 0;i<a2.length;i++){
count++;
}
}
return count;
}
}
You shouldn't use keywords such as "Integer" for variable identifiers.
There are some lingering questions I have, but I would simply use Java's builtin split() function on strings and use regex to split the string into significant figures (ignoring ending and leading zeroes). Then return the sum of the length of the strings . Here is the code for pure integers.
String myint = "000100101111220000020000";
String[] sig_figs = myint.split("(^0+|0+$)");
int sum = 0;
for(String fig : sig_figs)
{
sum += fig.length();
}
return sum;
If we include floats, there are other rules you would have to consider, such as zeroes after a decimal point count except if they are preceded by all zeroes (3.00 has 3, 0.03 has 1). In this case, the regex regrettably becomes much more contrived, but I would use something like "(^0+(\\.?)0*|(~\\.)0+$|\\.)" to split on. See code below (Note -- still works on integers)
String myfloat = "0.0120";
String [] sig_figs = myfloat.split("(^0+(\\.?)0*|(~\\.)0+$|\\.)");
int sum = 0;
for (String fig : sig_figs)
{
sum += fig.length();
}
return sum;
Here's a quick look into the regex:
^0+(\\.?)0* means one or more leading zeroes (0+) followed optionally by a decimal (\\.?) and then zero or more zeroes (0*).
(~\\.)0+$ means we want to take off ending zeroes (0+$), but only if they aren't preceded by a decimal ((~\\.)).
\\. means split whatever is left by the decimal point.
When you find a zero, start a separate count of zeroes. Keep incrementing the zero counter instead of the main counter each time you find a zero. If you find a nonzero number, add the zeroes count value to the main counter, and set the zero counter to 0 (restart it), as well as incrementing the main counter like normal for the nonzero number. If instead, you reach the end of the array of numbers, then just ignore the zero counter.
So, you will end up adding the zero counter to the main counter only if the zeroes are not trailing zeroes, and hence, sigfigs.
The following code will find out the number of 0s in a string
String s = "1234320300340";
int count = 0;
for(int i = 0; i<s.length(); i++){
if(s.charAt(i)== '0'){
count++;
}
}
System.out.println("total no of Zeros = "+ count);

Convert a string of numbers to an array in Java, where each number is a different slot

Suppose I have a string of 123456789. I would like to split this string and each number goes in a different slot in the array. I can't use the split() method because there is nothing to split on. How would I accomplish this in Java.
int x=123456789;
char[] array = x.toString().toCharArray();
int intarray[] = new int[array.length];
for (int i = 0; i < array.length; i++) {
intarray[i] = Integer.parseInt(array[i]);
}
And after this you intarray will be array of your numbers.
If your integer can be negative too, you must take it's absolute value and make same operations, and after that multiple first array value by -1. But I guess, it's not needed.
EDIT:
I think, I don't understand your question properly. If you want to split only string, you must use this lines only. I wrote about integers,which might be helpful too.
string x="123456789";
char[] array = x.toCharArray();
If you're only dealing with non-negative integers, the toCharArray() method should be suitable for you. It gives you the string as an array.
The String class has a neat method for doing this, toCharArray().
You can use the following to avoid creating Strings.
long x = x;
ByteBuffer bb = ByteBuffer.allocate(18);
if (x == 0) {
bb.put((byte) 0);
} else {
while (x > 0) {
bb.put((byte) (x % 10));
x /= 10;
}
}
int len = bb.position();
byte[] digits = new byte[len];
for (int i = 0; i < len; i++)
digits[i] = bb.get(len - i - 1);
is it compelsory that the data will be of single digit ?If the data may come in multiple digits then it will not be possible to identify whether the numeric value is of single digit of multiple digit ?
e.g. if it is 12(twelve) then if all string is 512 then how will you identify whether to represent 512 as 5,1,2 or 5,12 ?
if it is fix that the numbers will be in single digits and non negetives then toCharArray() of String class will work for you

Categories