Swap numbers in a string - java

I've the below program.
public class swapping {
public static void main(String[] args) {
String num = "31254";
int max = Integer.MIN_VALUE, maxIndex = 0;
for (int i = 0; i < num.length(); i++) {
if (num.charAt(i) > max) {
max = num.charAt(i);
maxIndex = i;
}
}
swap(num, num.charAt(0), maxIndex);
}
private static void swap(String num, char charAt, int maxIndex) {
System.out.println("number is " + num + " Initial char is " + charAt
+ " Maximum is " + maxIndex);
char t = charAt;
char s = num.charAt(maxIndex);
System.out.println("numbers:" + t + " " + s);
char temp = t;
t = s;
s = temp;
System.out.println("Final string after swap is " + num);
}
}
here my aim is to get the maximum number in the string to be swapped with the first number in the string. i.e. I want to convert 31254 to 51234. But i'm unable to know how to do this.
number is 31254 Initial char is 3 Maximum is 3
numbers:3 5
Final string after swap is 31254
Here the swapping is not getting done, the previous number is getting printed. please let me know how to print the desired output.
Thanks

Pay attention what you are passing to the method.
You are passing the actual character in the first and max position: 3 and 5 in this case.
But then, after you print them, you call:
char t = num.charAt(initial);
char s = num.charAt(max);
charAt expects the index of the character in the string. The index should be an integer, but you are passing it a char value (the character 3 and the character 5).
Now, in Java, characters are considered numbers between 0 and 65535 - the unicode value of the character. So it allows you to pass a character where you should have passed an integer. The unicode value of 3 is 51, and for 5 it's 53. So you are actually telling it "give me the character in the string num which is in position 51".
This is not what you intended.
Instead of doing that, you should make the method accept the index of the first character and the index of the max character. Then, using charAt will be correct. But pay attention to also use charAt for your print at the beginning.
private static void swap(String num, int initialIndex, int maxIndex) {
...
}
Your other problem is that you are not actually swapping the characters inside the string.
What you did was swap the variables that contain the two characters, t and s. So now t contains what s contained, and s contains what t contained.
However, this has no bearing on the original string num. You have not done anything with the string itself.
One thing to remember is that in Java, you cannot change a string. It's immutable. If you have a string object, Java doesn't give you any way to change things inside it. It only lets you read parts of it, not write.
What you can do is assign a new string value to num. In this new string, you will put the value of the max character in the 0 position, and put the value of what was in the first position, in the max character position. And you'll copy all the other characters in the same positions where they were.
So you'll need to create a temporary string, loop on the original string character by character, and in each position, ask yourself "what character should I add to my new string at this round?". And then add that character to the string with a + operator.
Finally, assign the new, temporary string to num.
(Note: there are more efficient ways to do this in Java, like using a StringBuffer or StringBuilder, but I get the impression that you are not there yet in your studies of Java).

try the below program.
String num = "31254";
int maxIndex = 0;
char maxString = num.charAt(0);
for (int i = 1; i < num.length(); i++) {
if (num.charAt(i) > maxString) {
maxString = num.charAt(i);
maxIndex = i;
}
}
System.out.println(maxString);
System.out.println(maxIndex);
String str1 = num.substring(1,maxIndex);
String str2 = num.substring(maxIndex+1,num.length());
String str3 = num.charAt(maxIndex)+str1+num.charAt(0)+str2;
System.out.println(str3);

Initial is a char. charAt use an integer, so the char will converted in the acii code of 3 wich is 51. So your line is equals to `num.charAt(51) and that is out of range.
So hyou have to change the signature of your mathod to private static void swap(String num, int initial, int max)

Here's how I would do it in just 3 lines. Note that for digits, chars are 1 byte each.
byte[] array = number.getBytes();
Arrays.sort(array);
number = number.replaceFirst("(.)(.*?)(" + (array[array.length - 1] - '0') + ")", "$3$2$1");
Not only is this code quite terse - using regex to perform the swap in one statement - it also automatically handles the edge case of the largest digit being at the start (in which case no match/replacement will be made).
Here's some test code:
String number = "31254";
byte[] array = number.getBytes();
Arrays.sort(array);
number = number.replaceFirst("(.)(.*?)(" + (array[array.length - 1] - '0') + ")", "$3$2$1");
System.out.println(number);
Output:
51234

Related

Finding the nth term in a sequence

I have a sequence, and I am trying to make a program to find the nth term of the sequence.
The sequence is as follows:
1, 11, 21, 1211, 111221, 312211...
In this sequence, each term describes the previous term. For example, "1211" means that the previous term; the previous term is "21" where there is one occurrence of a 2 and then one occurrence of a 1 (=1211). To get the third term, "21," you look at the second term: 11. There are two occurrences of a 1 which gives us "21."
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
System.out.println( Main.num(n-1, "1"));
}
public static String num(int times, String x){
if(times == 0){
return x;
}else{
//System.out.println("meow");
String y = "" + x.charAt(0);
int counter = 0;
for(int i = 1; i < x.length(); i++){
if(x.charAt(i) == x.charAt(i-1)){
counter++;
}else{
y += "" + counter + x.charAt(i-1);
counter = 0;
}
}
return num(times--, y);
}
//return "";
}
}
My code uses recursion to find the nth term. But, it gives us errors :(
First, I start of the method "num" by passing it the number of terms-1 (since the first term is already given) and the first term (1).
In the method num, we start off by using a conditional to establish the base case (when you are done finding the nth term).
If the base case is false, then you find the next term in the sequence.
This is a very cool sequence! I like that it is English based and not mathematical, haha. (Though now I wonder ... is there a formula we could make for the nth term? I'm pretty sure it's impossible or uses some crazy-level math, but just something to think about ...)
In your solution, the recursive logic of your code is correct: after you find each term, you repeat the method with your knew number and find the next term using that element, and end when you have determined the first n elements. Your base case is also correct.
However, the algorithm you developed for determining the terms in the sequence is the issue.
To determine the next element in the sequence, we want to:
Logical Error:
Create a empty variable, y, for your next element. The variable, counter, should not start at 0, however. This is because every element will ALWAYS have an occurrence of at least 1, so we should initialize int counter = 1;
Iterate through the characters in x. (You did this step correctly) We begin at i = 1, because we compare each character to the previous one.
If the current character is equal to the previous character, we increment counter by 1.
Otherwise, we concatenate counter and the character being repeated, to y. Remember, to reinitialize counter to 1, not 0.
Technical Errors:
Once we reach the end of iterating x, we need to concatenate our final counter and character to y, since the else statement for the final characters will never run in our for loop.
This is done with the following code: y += "" + counter + x.charAt(x.length() - 1);
Finally, when you are doing your recursive call, you should do --times instead of times--. The difference between these two parameters is that with your original code, you are post-decrementing. This means the value of times is decreasing after the method call, when we want the decreased value to be sent into the method. To solve this, we need to pre-decrement, by doing --times.
import java.util.*;
class CoolSequence {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
System.out.println(num(n, "1"));
}
public static String num(int times, String x){
if(times == 0){
return x;
}
else{
String y = "";
int counter = 1;
for(int i = 1; i < x.length(); i++){
if(x.charAt(i) == x.charAt(i - 1)){
counter++;
}
else{
y += "" + counter + x.charAt(i - 1);
counter = 1;
}
}
y += "" + counter + x.charAt(x.length() - 1);
return num(--times, y);
}
}
}
Testing:
6
13112221
An alternative approach would be using an iterative method:
import java.util.*;
class CoolSequence2 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
ArrayList<String> nums = new ArrayList<String>();
int n = scan.nextInt();
String val = "1";
for(int i = 0; i < n; i++){
String copy = val;
val = "";
while(!copy.equals("")){
char curr = copy.charAt(0);
int ind = 0;
int cons = 0;
while(ind < copy.length() && curr == copy.charAt(ind)){
cons += 1;
ind += 1;
}
val += String.valueOf(cons) + copy.charAt(cons - 1);
copy = copy.substring(cons);
}
nums.add(val);
}
System.out.println(nums.get(nums.size() - 1));
}
}
6
13112221
In this method, we use a for loop to iterate through n terms. To determine each element, we do a similar method to your logic:
We create an empty string, val, to hold the new element, and store our current element in copy. We also initialize a cons, similar to your counter.
While copy is not empty, we iterate through copy and increment cons until there is an element that is not equal to the next element.
When this occurs, we concatenate cons and the repeated element to val, like in your code. Then, we cut out the repeated elements from copy and continue the process.
We add the new value of val to nums, and keep iterating through the n elements.
I hope these two methods of approaching your problem helped! Please let me know if you have any further questions or clarifications :)
You can use Pattern with backreference.
The regular expression "(.)\\1*" matches any single character ("(.)") and zero or more sequences of the same character ("\\1*"). "\\1" is called a backreference, it refers to the string enclosed in parentheses 1st.
For example, it matches 111, 22 and 1 for 111221.
replaceAll() calls the lambda expression specified by the argument each time it matches. The lambda expression receives a MatchResult and returns a string. The matched string is replaced with the result.
The lambda expression in this case concatenates the length of the matched string (match.group().length()) and the first character (match.group(1)).
static final Pattern SEQUENCE_OF_SAME_CHARACTER = Pattern.compile("(.)\\1*");
static String num(int times, String x) {
for (int i = 0; i < times; ++i)
x = SEQUENCE_OF_SAME_CHARACTER.matcher(x).replaceAll(
match -> match.group().length() + match.group(1));
return x;
}
public static void main(String[] args) {
for (int i = 1; i <= 8; ++i)
System.out.print(num(i - 1, "1") + " ");
}
output:
1 11 21 1211 111221 312211 13112221 1113213211

How I can count duplicate with Strings?

I am new to programming , I am developing with strings , I am not yet with Hash Maps my only problem is the last letter. The last letter for example s The value contains 2 instead one. How can I do that?
public static void main(String[] args) {
String word = "Chris",
curr_char,
next_char;
int length_string = word.length(),
count = 0;
char end_letter = word.charAt(word.length()-1);
String end = Character.toString(end_letter);
for(int index = 0; index < word.length(); index++)
{
curr_char = word.substring(index, index+1);
for(int next_index = 0;next_index<word.length(); next_index++)
{
next_char = word.substring(next_index, next_index+1);
if (curr_char.equalsIgnoreCase(next_char))
{
count = 1;
}
if(curr_char.contains(end))
{
count = count + 1;
}
}
System.out.println(word.charAt(index) + " " + count);
}
}
You have some issues in your algorithm logic. The algorithm will not work with strings such as "Chriss" or "Chcriss". Your output with input string "Chriss" would be
C 1
h 1
r 1
i 1
s 2
s 1
Additionally, you have 2 iterations, which makes the algorithm not so efficient. An algorithm to be efficient should take less time (high speed) & less space (less memory).
Your above problem is usually solved by having an integer array, say charArrayCount , of size 26, as there are 26 letters in the English alphabet. Each element of this integer array represents a character in the alphabet & is used to count how many times it appears in a string. You would iterate through each character in your string & use the formula,
charArrayCount[25 - ('z' - ch)] += 1;
where 'ch' would be a character in your string. You could then iterate through your array 'charArrayCount' & get those values > 1. You would have to take care of upper case & lower case characters.
In this case, you have only 1 iteration through the string & no matter how long your string is, say a thousand characters, you create space for an integer array of 26 elements only.
Try this & see if it helps.
This code runs perfect now :
public static void main(String args[]) {
String word = "Chris" , curr_char , next_char;
int length_string = word.length();
char end_letter = word.charAt(word.length()-1);
String end = Character.toString(end_letter);
for(int index = 0; index <word.length(); index++)
{
int count = 0; //resetting the value of count every time
curr_char = word.substring(index, index+1);
for(int next_index = 0;next_index<word.length(); next_index++)
{
next_char = word.substring(next_index, next_index+1);
if (curr_char.equalsIgnoreCase(next_char))
{
count = count + 1;
//if any character repeats it increase the value of count
}
}
System.out.println(word.charAt(index) + " " + count);
}
}
Test this once...

How do you get the numerical value from a string of digits?

I need to add certain parts of the numerical string.
for example like.
036000291453
I want to add the numbers in the odd numbered position so like
0+6+0+2+1+5 and have that equal 14.
I tried the charAt(0)+charAt(2) etc, but it returns the digit at those characters instead of adding them. Thanks for your help.
Use charAt to get to get the char (ASCII) value, and then transform it into the corresponding int value with charAt(i) - '0'. '0' will become 0, '1' will become 1, etc.
Note that this will also transform characters that are not numbers without giving you any errors, thus Character.getNumericValue(charAt(i)) should be a safer alternative.
String s = "036000291453";
int total = 0;
for(int i=0; i<s.length(); i+=2) {
total = total + Character.getNumericValue(s.charAt(i));
}
System.out.println(total);
You can use Character.digit() method
public static void main(String[] args) {
String s = "036000291453";
int value = Character.digit(s.charAt(1), 10);
System.out.println(value);
}
Below code loops through any number that is a String and prints out the sum of the odd numbers at the end
String number = "036000291453";
int sum = 0;
for (int i = 0; i < number.length(); i += 2) {
sum += Character.getNumericValue(number.charAt(i));
}
System.out.println("The sum of odd integers in this number is: " + sum);
I tried the charAt(0)+charAt(2) etc, but it returns the digit at those
characters instead of adding them.
Character.getNumericValue(string.charAt(0));

Java error: char cannot be dereferenced

Here is what the teacher asked me to do:
Enter a phone number (set up a string-type object for the phone number)
example:
(703) 323-3000
Display the phone number, using a format like the following:
Example 1:
The phone number you entered is 703-323-3000.
Display the content of the array that holds the count for each digit in the string. Use a format similar to the following:
Example:
Digit 0 showed up 4 times.
Digit 1 showed up 0 times.
Digit 2 showed up 1 times.
Digit 3 showed up 4 times.
Digit 4 showed up 0 times.
Digit 5 showed up 0 times.
Digit 6 showed up 0 times.
Digit 7 showed up 1 times.
Digit 8 showed up 0 times.
Digit 9 showed up 0 times
The teacher also provided us with an algorithm as a hint:
set up an integer array of size 10
initialize each element to zero
input string of phone number
set SIZE = length of the string
set up a loop to iterate SIZE times
{
get next character
update array appropriately
(for example: if the character is '7' then increment array[7] by 1.
}
Display BOTH using appropriate messages:
the original phone number
contents of the array (using a loop).
Here is My code but it shows the error I mentioned when i use the equals() method, and displays a wrong answer if i use ==. Please Help.
public class Phones
{
public static void main(String[] args)
{
int Num[] = {0,0,0,0,0,0,0,0,0,0};
String Phone = "703-323-3000";
int SIZE = Phone.length() - 1;
for(int count=0; count<= SIZE; count++)
{
for(int counter = 0; counter <= SIZE; counter++)
{
if(Phone.charAt(counter).equals(count))
Num[count]++;
}
System.out.println("Digit " + count + " showed up " + Num[count] + " times");
}
}
}
This is my first time on this site, so sorry in advance if this is too long or incomprehensible. Thank you.
The reason you get the wrong answer with == is that you're comparing a char with an int incorrectly. In short, you're comparing counter with the unicode value of the characters, rather than with the number that the character represents. (For "normal" characters like letters, numbers and simple punctuation, the unicode values are the same as the ASCII values.)
The char '0' does not have an int value 0 -- it has the unicode value for the char 0, which is 0x0030 (aka 48 in base 10 -- the 0x format shows it in hex). By comparing the char the way you're doing, the first comparison will only be true if the char is the so-called "null char" 0x0000 (not to be confused with null, which is a null reference!), which won't happen for any sort of "normal" input.
Instead, you need a way to compare chars with ints. The easiest way to do this is to subtract the '0' char's value from the current char:
int charDistanceFromZero = Phone.charAt(counter) - '0';
If that distance is less than 0 or greater than 9, you have a char that's not a number. Otherwise, charDistanceFromZero is the offset you need into the array.
This works because the characters for the number digits start at 0 and are sequential from there. Try computing charDistanceFromZero for a few of them to get a feel for how it works out for getting the array index.
charAt will return a value of type char, which is the reason why you cannot do .equals(...).
Also, the characters representing the digits are in ['0' .. '9'], which isn't the same as the interval [0 .. 9]. You need to translate the range by subtracting '0'.
The reason for your error is that charAt returns a char, which is a primitive type. You need to have an object, not a primitive, in order to be able to call a method, such as .equals. Moreover, when you tried to use == in place of .equals, you were comparing a char to an int value. It's all right to do this, so long as you remember that the int value of a character is its encoded value, so 48 for '0', 49 for '1' and so on.
To solve this problem, it's best to use the methods that come for free in Java's Character class; notably isDigit, which determines whether a character is a digit, and getNumericValue, which converts a character to the number that it represents.
It's also possible to dispense with the outer loop entirely, since once you've converted each digit character to its numeric value, you already have the index in the array that you want to increment. So here is a much cleaner solution, that does not use nested loops at all.
public class Phones{
public static void main(String[] args){
int counters[] = new int[10];
String phone = "703-323-3000";
for (char eachCharacter : phone.toCharArray()) {
if (Character.isDigit(eachCharacter)) {
int digit = Character.getNumericValue(eachCharacter);
counters[digit]++;
}
}
for(int digit = 0; digit < 10; digit++) {
if (counters[digit] != 0) {
System.out.format("Digit %d showed up %d times.%n", digit, counters[digit]);
}
}
}
}
Here, the first loop traverses your input string, incrementing the array index corresponding to each digit in the string. The second loop just prints out the counts that it's found.
Other answers are fine... But to reduce ambiguity in code I generally just send the string into a char array before doing any control flows... And as noted, 'Zero' is at Unicode Code Point 48 so you need to subtract that value from the character index.
char[] number = "212-555-1212".toCharArray();
for(int i = 0; i < numbers.length; i++) {
// do something groovy with numbers[i] - 48
}
So for this solution you might do something like this....
String phone = "212-555-1212".replaceAll( "[^\\d]", "" );
int[] nums = new int[phone.length()];
int[] queue = new int[phone.length()];
for(int i = 0; i < nums.length; i++) {
nums[i] = phone.toCharArray()[i] - 48;
for(int num : nums) {
if( nums[i] == num ) {
queue[i] += 1;
}
}
System.out.println( "Number: " + nums[i] + " Appeared: " + queue[i] + " times." );
}

(Java) Convert a string of numbers to an array of ints

I'm trying to convert a string filled with 16 digits into an array of ints where each index holds the digit of its respective index in the string. I'm writing a program where I need to do math on individual ints in the string, but all of the methods I've tried don't seem to work. I can't split by a character, either, because the user is inputting the number.
Here's what I have tried.
//Directly converting from char to int
//(returns different values like 49 instead of 1?)
//I also tried converting to an array of char, which worked,
//but then when I converted
//the array of char to an array of ints, it still gave me weird numbers.
for (int count = 0; count <=15; count++)
{
intArray[count] = UserInput.charAt(count);
}
//Converting the string to an int and then using division to grab each digit,
//but it throws the following error (perhaps it's too long?):
// "java.lang.NumberFormatException: For input string: "1234567890123456""
int varX = Integer.parseInt(UserInput);
int varY = 1;
for (count=0; count<=15; count++)
{
intArray[count]= (varX / varY * 10);
}
Any idea what I should do?
how about this:
for (int count = 0; count < userInput.length; ++count)
intArray[count] = userInput.charAt(count)-'0';
I think that the thing that is a bit confusing here is that ints and chars can be interpited as eachother. The int value for the character '1' is actually 49.
Here is a solution:
for (int i = 0; i < 16; i++) {
intArray[i] = Integer.valueOf(userInput.substring(i, i + 1));
}
The substring method returns a part of the string as another string, not a character, and this can be parsed to an int.
Some tips:
I changed <= 15 to < 16. This is the convetion and will tell you how many loop interations you will actually go throug (16)
I changed "count" to "i". Another convention...

Categories

Resources