How to find out if the char in string is a letter or a number?
I.e I have a string "abc2e4", I need to find the ints, square them, and put the answer back in the string (no extra operations with the letters), so the new string would be "abc4e16".
Im incredibly lost with this exercise, so any help would be great :D
You can do it using Regular Expression
public static String update(String str) {
final Pattern pattern = Pattern.compile("\\D+|\\d+");
final Matcher matcher = pattern.matcher(str);
StringBuilder buf = new StringBuilder();
int pos = 0;
while (matcher.find(pos)) {
str = matcher.group();
buf.append(Character.isDigit(str.charAt(0)) ? (int)Math.pow(Integer.parseInt(str), 2) : str);
pos = matcher.end();
}
return buf.toString();
}
Java provides a method to check whether a character is a digit. For this you can use Character.isDigit(char).
public static String squareNumbers(String input) {
StringBuilder output = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i); // get char at index
if (Character.isDigit(c)) // check if the char is a digit between 0-9
output.append((int) Math.pow(Character.digit(c, 10), 2)); // square the numerical value
else
output.append(c); // keep if not a digit
}
return output.toString();
}
This will iterate any passed string character by character and square each digit it finds. If for example 2 digits are right next to each other they will be seen as individual numbers and squared each and not as one number with multiple digits.
squareNumbers("10") -> "10"
squareNumbers("12") -> "14"
squareNumbers("abc2e4") -> "abc4e16"
My logic only squares single digit numbers.
For eg - if you provide input he13llo, the output would be he19llo and not he169llo.
Scanner in = new Scanner(System.in) ;
String str = in.next() ;
String ans = str ;
for (int i = 0 ; i < str.length() ; i++)
{
char ch = str.charAt(i) ;
if((ch - '0' >= 0) && (ch - '9' <= 0))
{
int index = i ;
int num = ch - '0' ;
int square = num * num ;
ans = ans.substring(0 ,index) + square + ans.substring(index+1) ;
}
}
System.out.println(ans) ;
}
Related
I'm trying to write a non-recursive Java method called showStar, which takes a string, and generates ALL possible combinations of that string without the mask “*” characters.
receiving this as an input "1011*00*10",
the method `showStar` will display output like:
1011000010
1011000110
1011100010
1011100110
I tried this way, however, as soon as the number of possible cases is more than the String length, the output is not exact.
Here is my code.
public static void showStar(String s){
String save;
int count = 0;
int poss;
save = s.replace('*','0');
StringBuilder myString = new StringBuilder(save);
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '*' && myString.charAt(i) == '0') {
myString.setCharAt(i, '1');
System.out.println(myString);
}
}
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '*' && myString.charAt(i) == '1') {
myString.setCharAt(i, '0');
System.out.println(myString);
}
}
}
Say there are k *s. Then there are 2^k solutions. You can generate these by copying the bits from the integers 0 - 2^k-1 in order. (adding sufficient leading zeroes)
E.g. 1**1:
0 = 00 => 1001
1 = 01 => 1011
2 = 10 => 1101
3 = 11 => 1111
Here a recursive algoritm works just perfectly:
You check if an input string contains an asterisk '*' by using an x = str.indexOf('*');
If no asterisk is present (x == -1), you just print the string and return
Otherwise, you replace the asterisk at the position to '0' and '1' and call showStar() recursively for both replacements
public static void showStar(String str) {
int x = str.indexOf('*');
if(x == -1) {
System.out.println(str);
return;
}
String prefix = str.substring(0, x);
String suffix = str.substring(x + 1);
for (char i = '0'; i <= '1'; i++) {
showStar(prefix + i + suffix);
}
}
Update
In non-recursive implementation we need to collect the asterisk positions, then prepare a binary representation and set appropriate bits at the known positions:
public static void showStar(String str) {
int[] xs = IntStream.range(0, str.length())
.filter(i -> str.charAt(i) == '*')
.toArray();
int num = (int) Math.pow(2, xs.length); // 2^n variants for n asterisks
String format = xs.length > 0 ? "%" + xs.length + "s" : "%s"; // fix if no '*'
for (int i = 0; i < num; i++) {
String bin = String.format(format, Integer.toBinaryString(i))
.replace(' ', '0'); // pad leading zeros
StringBuilder sb = new StringBuilder(str);
// set 0 or 1 in place of asterisk(s)
for (int j = 0; j < xs.length; j++) {
sb.setCharAt(xs[j], bin.charAt(j));
}
System.out.println(sb);
}
}
I'm trying to count the number of occurrences of letters that are in string. The code that I have written technically does what I want, but not the way I want to do it. For example, if I input "Hello World", I want my code to return "a=0 b=0 c=0 d=0 e=1 etc...." with the code I have written it returns "H=1, e=1, l=2 etc...."
Also how would I make sure that it is not case sensitive and it doesn't count spaces.
Code:
import java.util.Scanner;
public class Sequence {
private static Scanner scan = null;
public static void main(String[] args) {
scan = new Scanner(System.in);
String str = null;
System.out.print("Type text: ");
str = scan.nextLine();
int[] count = new int[255];
int length = str.length();
for (int i = 0; i < length; i++)
{
count[str.charAt(i)]++;
}
char[] ch = new char[str.length()];
for (int i = 0; i < length; i++)
{
ch[i] = str.charAt(i);
int find = 0;
for (int j = 0; j <= i; j++)
{
if (str.charAt(i) == ch[j])
find++;
}
if (find == 1)
{
System.out.print(str.charAt(i) + "=" + count[str.charAt(i)] + " ");
}
}
}
}
As I hinted in my original comment you only need an array of 26 int(s) because there are only 26 letters in the alphabet. Before I share the code, it is important to note that Java char is an integral type (and, for example, 'a' + 1 == 'b'). That property is important, because it allows you to determine the correct offset in an array (especially if you force the input to lower case). Something like,
Scanner scan = new Scanner(System.in);
System.out.print("Type text: ");
String str = scan.nextLine();
int[] count = new int[26];
for (int i = 0; i < str.length(); i++) {
char ch = Character.toLowerCase(str.charAt(i)); // not case sensitive
if (ch >= 'a' && ch <= 'z') { // don't count "spaces" (or anything non-letter)
count[ch - 'a']++; // as 'a' + 1 == 'b', so 'b' - 'a' == 1
}
}
for (int i = 0; i < count.length; i++) {
if (count[i] != 0) {
System.out.printf("%c=%d ", 'a' + i, count[i]);
}
}
System.out.println();
If you really want to see all of the letters that have counts of zero (seems pointless to me), change
if (count[i] != 0) {
System.out.printf("%c=%d ", 'a' + i, count[i]);
}
to remove the if and just
System.out.printf("%c=%d ", 'a' + i, count[i]);
Change str = scan.nextLine(); to str = scan.nextLine().toLowerCase().replaceAll("\\s+","");
.toLowerCase() is a method which makes every char in the string lowercase.
.replaceAll() is a method which replaces one char with another. In this case, it replaces whitespaces with nothing.
I hope this isn't too much of a stupid question, I have looked on 5 different pages of Google results but haven't been able to find anything on this.
What I need to do is convert a string that contains all Hex characters into ASCII for example
String fileName =
75546f7272656e745c436f6d706c657465645c6e667375635f6f73745f62795f6d757374616e675c50656e64756c756d2d392c303030204d696c65732e6d7033006d7033006d7033004472756d202620426173730050656e64756c756d00496e2053696c69636f00496e2053696c69636f2a3b2a0050656e64756c756d0050656e64756c756d496e2053696c69636f303038004472756d2026204261737350656e64756c756d496e2053696c69636f30303800392c303030204d696c6573203c4d757374616e673e50656e64756c756d496e2053696c69636f3030380050656e64756c756d50656e64756c756d496e2053696c69636f303038004d50330000
Every way I have seen makes it seems like you have to put it into an array first. Is there no way to loop through each two and convert them?
Just use a for loop to go through each couple of characters in the string, convert them to a character and then whack the character on the end of a string builder:
String hex = "75546f7272656e745c436f6d706c657465645c6e667375635f6f73745f62795f6d757374616e675c50656e64756c756d2d392c303030204d696c65732e6d7033006d7033006d7033004472756d202620426173730050656e64756c756d00496e2053696c69636f00496e2053696c69636f2a3b2a0050656e64756c756d0050656e64756c756d496e2053696c69636f303038004472756d2026204261737350656e64756c756d496e2053696c69636f30303800392c303030204d696c6573203c4d757374616e673e50656e64756c756d496e2053696c69636f3030380050656e64756c756d50656e64756c756d496e2053696c69636f303038004d50330000";
StringBuilder output = new StringBuilder();
for (int i = 0; i < hex.length(); i+=2) {
String str = hex.substring(i, i+2);
output.append((char)Integer.parseInt(str, 16));
}
System.out.println(output);
Or (Java 8+) if you're feeling particularly uncouth, use the infamous "fixed width string split" hack to enable you to do a one-liner with streams instead:
System.out.println(Arrays
.stream(hex.split("(?<=\\G..)")) //https://stackoverflow.com/questions/2297347/splitting-a-string-at-every-n-th-character
.map(s -> Character.toString((char)Integer.parseInt(s, 16)))
.collect(Collectors.joining()));
Either way, this gives a few lines starting with the following:
uTorrent\Completed\nfsuc_ost_by_mustang\Pendulum-9,000 Miles.mp3
Hmmm... :-)
Easiest way to do it with javax.xml.bind.DatatypeConverter:
String hex = "75546f7272656e745c436f6d706c657465645c6e667375635f6f73745f62795f6d757374616e675c50656e64756c756d2d392c303030204d696c65732e6d7033006d7033006d7033004472756d202620426173730050656e64756c756d00496e2053696c69636f00496e2053696c69636f2a3b2a0050656e64756c756d0050656e64756c756d496e2053696c69636f303038004472756d2026204261737350656e64756c756d496e2053696c69636f30303800392c303030204d696c6573203c4d757374616e673e50656e64756c756d496e2053696c69636f3030380050656e64756c756d50656e64756c756d496e2053696c69636f303038004d50330000";
byte[] s = DatatypeConverter.parseHexBinary(hex);
System.out.println(new String(s));
String hexToAscii(String s) {
int n = s.length();
StringBuilder sb = new StringBuilder(n / 2);
for (int i = 0; i < n; i += 2) {
char a = s.charAt(i);
char b = s.charAt(i + 1);
sb.append((char) ((hexToInt(a) << 4) | hexToInt(b)));
}
return sb.toString();
}
private static int hexToInt(char ch) {
if ('a' <= ch && ch <= 'f') { return ch - 'a' + 10; }
if ('A' <= ch && ch <= 'F') { return ch - 'A' + 10; }
if ('0' <= ch && ch <= '9') { return ch - '0'; }
throw new IllegalArgumentException(String.valueOf(ch));
}
Check out Convert a string representation of a hex dump to a byte array using Java?
Disregarding encoding, etc. you can do new String (hexStringToByteArray("75546..."));
So as I understand it, you need to pull out successive pairs of hex digits, then decode that 2-digit hex number and take the corresponding char:
String s = "...";
StringBuilder sb = new StringBuilder(s.length() / 2);
for (int i = 0; i < s.length(); i+=2) {
String hex = "" + s.charAt(i) + s.charAt(i+1);
int ival = Integer.parseInt(hex, 16);
sb.append((char) ival);
}
String string = sb.toString();
//%%%%%%%%%%%%%%%%%%%%%% HEX to ASCII %%%%%%%%%%%%%%%%%%%%%%
public String convertHexToString(String hex){
String ascii="";
String str;
// Convert hex string to "even" length
int rmd,length;
length=hex.length();
rmd =length % 2;
if(rmd==1)
hex = "0"+hex;
// split into two characters
for( int i=0; i<hex.length()-1; i+=2 ){
//split the hex into pairs
String pair = hex.substring(i, (i + 2));
//convert hex to decimal
int dec = Integer.parseInt(pair, 16);
str=CheckCode(dec);
ascii=ascii+" "+str;
}
return ascii;
}
public String CheckCode(int dec){
String str;
//convert the decimal to character
str = Character.toString((char) dec);
if(dec<32 || dec>126 && dec<161)
str="n/a";
return str;
}
To this case, I have a hexadecimal data format into an int array and I want to convert them on String.
int[] encodeHex = new int[] { 0x48, 0x65, 0x6c, 0x6c, 0x6f }; // Hello encode
for (int i = 0; i < encodeHex.length; i++) {
System.out.print((char) (encodeHex[i]));
}
For example if the binary string is 10100010 then the program must return 1st,3rd and 7th i.e the positions of the 1's.
Below is the code which you are looking for note that regex starts with zeroth position.
String regex = "[1]";
String data = "10100010";
Matcher m = Pattern.compile(regex).matcher(data);
while(m.find())
{
System.out.println(m.group() + " => " + (m.start()+1) );
}
Two options:
Convert it to an integer/long (if possible) and then shift one bit each time and check if it's 1. For example:
String str = "10100010";
Integer x = Integer.valueOf(str);
int len = str.length();
while (x != 0) {
if (x & 0x1 == 1) {
System.out.println(len);
}
len--;
x >>= 1;
}
Scan the string by-index and check if its' value is 1:
for (int i = 0; i < str.length(); i++) {
if (str.chatAt(i) == '1') {
//print
}
}
char[] str="10100010".toCharArray();
for(int i=0;i<str.length;i++){
if(str[i]=='1'){
int setBit=1;
setBit+=i;
System.out.println(setBit+"th");
}
}
String word = "ABCD";
StringBuffer str = new StringBuffer (word);
int counter = 0;
for (int ch = 0; ch < word.length(); ch ++)
{
int number = word.charAt(ch)- 'A' + 1;
str.setCharAt(counter, (char) number);
if (ch != word.length ()-1)
str.insert(counter +1, '-');
counter += 2;
}
System.out.println (str);
}
I want my output to be 1-2-3-4, so A = 1 and B= 2.... etc. We can assume that all the input are in upper case. But the my code produce random symbols. So how do I fix the code to produce 1-2-3-4 without re writing the whole thing?
You're only missing the conversion from int back to char. The line
str.setCharAt(counter, (char) number);
should be
str.setCharAt(counter, (char) ('0' + number));