String input = stack.pop();
if ((index = input.indexOf('*')) != -1) {
for (char c = '0'; c <= '1'; c++) {
input = input.substring(0, index) + c +
input.substring(index + 1);
stack.push(input);
}
}
I'm struggling to understand what's happening in the for loop. Can someone clarify how it iterates? I'm not used to having something other than the length of the array as the second parameter.
When you write for loop like this c have value = 48 accord to ascii table when you increment c it go up to 49 which is equal to 1 also from ascii. So now if you know that you can change your code to this
for (int c = 48; c <= 49; c++)
{
//your code
}
And it is the same. But if you concatenate string like you did value 48 is convert to 0,so * is gonna be replace with 0, in next iteration will be replace with 1.
So here is the thing.
I have to write code to show a binary number X's next smallest "code-X number" which is bigger than binary number X.
code-X number is a binary number which have no continuously 1. For example: 1100 is not a code X number because it has 11, and 1001001001 is a code-X number
Here is my code
String a = "11001110101010";
String b = "";
int d = 0;
for(int i = a.length()-1; i>0;i--){
if(a.charAt(i) == '1' && a.charAt(i-1)=='1'){
while(a.charAt(i)=='1'){
b = b + '0';
if(i!=0){i--;}
d++;
}
}
b = b + a.charAt(i);
}
StringBuffer c = new StringBuffer(b);
System.out.println(c.reverse());
I plan on copy the binary string to string b, replace every '1' which next i is '1' into '0' and insert an '1'
like:
1100 ---> 10000
but i have no idea how to do it :)
May you help me some how? Thanks
Try this. This handles arbitrary length bit strings. The algorithm is as follows.
Needed to conditionally modify last two bits to force a change if the number is not a codeEx number. This ensures it will be higher. Thanks to John Mitchell for this observation.
Starting from the left, find the first group of 1's. e.g 0110
If not at the beginning replace it with 100 to get 1000
Otherwise, insert 1 at the beginning.
In all cases, replace everything to the right of the grouping with 0's.
String x = "10000101000000000001000001000000001111000000000000110000000000011011";
System.out.println(x.length());
String result = codeX(x);
System.out.println(x);
System.out.println(result);
public static String codeX(String bitStr) {
StringBuilder sb = new StringBuilder(bitStr);
int i = 0;
int len = sb.length();
// Make adjust to ensure new number is larger than
// original. If the word ends in 00 or 10, then adding one will
// increase the value in all cases. If it ends in 01
// then replacing with 10 will do the same. Once done
// the algorithm takes over to find the next CodeX number.
if (s.equals("01")) {
sb.replace(len - 2, len, "10");
} else {
sb.replace(len- 1, len, "1");
}
while ((i = sb.indexOf("11")) >= 0) {
sb.replace(i, len, "0".repeat(len - i));
if (i != 0) {
sb.replace(i - 1, i + 2, "100");
} else {
sb.insert(i, "1");
}
}
String str = sb.toString();
i = str.indexOf("1");
return i >= 0 ? str.substring(i) : str;
}
Prints
10000101000000000001000001000000001111000000000000110000000000011011
10000101000000000001000001000000010000000000000000000000000000000000
Using raw binary you can use the following.
public static void main(String[] args) {
long l = 0b1000010100000000010000010000000011110000000000110000000000011011L;
System.out.println(
Long.toBinaryString(nextX(l)));
}
public static long nextX(long l) {
long l2 = l >>> 1;
long next = Long.highestOneBit(l & l2);
long cutoff = next << 1;
long mask = ~(cutoff - 1);
return (l & mask) | cutoff;
}
prints
1000010100000000010000010000000010000000000000000000000000000000
EDIT: Based on #WJS correct way to find the smallest value just larger.
This is a slight expansion WJS' 99% correct answer.
There is just one thing missing, the number is not incremented if there are no consecutive 1's in the original X string.
This modification to the main method handles that.
Edit; Added an else {}. Starting from the end of the string, all digits should be inverted until a 0 is found. Then we change it to a 1 and break before passing the resulting string to WJS' codeX function.
(codeX version does not include sb.replace(len-2,len,"11");)
public static void main(String[] args) {
String x = "10100";
StringBuilder sb = new StringBuilder(x);
if (!x.contains("11")) {
for (int i = sb.length()-1; i >= 0; i--) {
if (sb.charAt(i) == '0') {
sb.setCharAt(i, '1');
break;
} else {
sb.setCharAt(i, '0');
}
}
}
String result = codeX(sb.toString());
System.out.println(x);
System.out.println(result);
}
I want to create a loop where when you add a number, it gives you the equivalent character in that position in the alphabet. For example, a = 0, b = 1 etc..
I've already created that and it works, but the problem I have is that when it reaches 26, I would like it go back and continue the loop. For example, 25 is z, so 27 should be b.
Code:
char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toLowerCase().toCharArray();
if (i < 0)
{
return null;
}
if(i > 25)
{
i = 0;
}
return Character.toString(alphabet[i]); //converts character to String and returns the character
}
You can use the modulo operation on i.
char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toLowerCase().toCharArray();
int i =30;
System.out.println(alphabet[i % alphabet.length]);
You don't need any arrays or loops at all. Just do this:
return (char)('a' + (i % 26));
Try using a modulo operator for your indices. For example,
char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toLowerCase().toCharArray();
if (i < 0) return;
i = i % 26;
return Character.toString(alphabet[i]);
Or
char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toLowerCase().toCharArray();
if (i > 0)
return Character.toString(alphabet[i % 26]);
else
return;
I am trying to solve a problem . Hoping for some help here.
Objective: Find a number which is immediate next to input and contains only 4 and 7 in it.
Input : 1234
Output: 4444
Input : 4476
output: 4477
Input : 8327
Output : 44444
I am not looking for incrementing number and each time checking string characters for the pattern. That would be too slow for large numbers.
static String toOutput (int a) {
// I am trying here all the possible other ways
}
Check this answer. Hope this helps :)
private static String toOutput(int n) {
String input = String.valueOf(n+1);
// create input character array and output character array of one more in size
char[] inputChars = input.toCharArray();
char[] outputChars = new char[inputChars.length + 1];
boolean extra = false; //carry forward
// traverse input array from last position to first position
for (int i = inputChars.length - 1; i >= 0; i--) {
// for all other positions except last position check whether number is changed
// (i.e. apart from 4 or 7),
// change all higher digits in output array to 4
if ((i + 1) < inputChars.length) {
if (inputChars[i] != '4' && inputChars[i] != '7') {
for (int j = i + 1; j < inputChars.length; j++) {
outputChars[j + 1] = '4';
}
}
}
// if extra is true that means it is carry forward
if (extra == true) {
inputChars[i] = (char) ((int) inputChars[i] + 1);
}
// if input digit is less than equal to 4 output digit is 4 , extra is false
if (inputChars[i] <= '4') {
outputChars[i + 1] = '4';
extra = false;
}
// if input digit is between 4 to 7 output digit is 7 , extra is false
else if (inputChars[i] <= '7') {
outputChars[i + 1] = '7';
extra = false;
}
// if input digit is more than 7 output digit is 4 , extra is true
else {
outputChars[i + 1] = '4';
extra = true;
}
}
// if carry forward is true, make extra digit to 4 otherwise it is not required
if (extra == true) {
outputChars[0] = '4';
} else {
outputChars[0] = ' ';
}
return new String(outputChars).trim();
}
static String toOutput (long a) {
LinkedList<Long> q = new LinkedList<Long>();
q.add(4L);
q.add(7L);
while(!q.isEmpty()){
Long curr = q.pop();
if(curr>a)
return String.valueOf(curr);
q.add(curr*10+4);
q.add(curr*10+7);
}
return "";
}
This will solve the problem in close to O(LogN)
Since this is fundamentally a manipulation of character strings, a plausible solution is to use string functions, particularly regular expressions. Here's a compact solution:
class Incrementer {
Pattern p;
public Incrementer() {
p = Pattern.compile("(?:([47]*)([0-6]))?(.*)");
}
public String next(String s) {
Matcher m = p.matcher(s);
m.lookingAt();
return (m.group(1)==null
? '4'
: m.group(1) + (m.group(2).charAt(0) >= '4' ? '7' : '4'))
+ m.group(3).replaceAll(".", "4");
}
}
See it here.
(I'm not at all a Java programmer. Coding suggestions welcome.)
The regular expression matches the prefix of any sequence of legal digits (4 or 7) followed by an incrementable digit ( < 7). If that prefix is not matchable, the answer must be one digit longer, so it must start with the smallest legal digit (4). If the prefix is matchable, the prefix must be modified by bumping the last digit to the next legal digit. In both cases, all the digits following the (possibly empty) prefix are replaced with the smallest legal digit.
Of course, this could be done without actual regular expressions. The following essentially uses a state machine which implements the regular expression, so it might be faster. (Personally I find the regex version easier to verify, but YMMV):
public static String next(String s)
{
int toinc = -1;
for (int i = 0; i < s.length(); ++i) {
char c = s.charAt(i);
if (c < '7') {
toinc = i;
if (c != '4') break;
} else if (c > '7') break;
}
char[] outChars;
// Copy the prefix up to and including the character to be incremented
if (toinc < 0) {
outChars = new char[s.length() + 1];
} else {
outChars = new char[s.length()];
for (int i = 0; i < toinc; ++i)
outChars[i] = s.charAt(i);
// Increment the character to be incremented
outChars[toinc] = s.charAt(toinc) >= '4' ? '7' : '4';
}
// Fill with 4's.
for (int i = toinc + 1; i < outChars.length; ++i)
outChars[i] = '4';
return new String(outChars);
}
See it here.
*
public class PatternTest {
private static final char FOUR = '4';
private static final char SEVEN = '7';
public static void main(String[] args) {
Scanner scanner = new Scanner(new InputStreamReader(System.in));
String value = scanner.next();
char startChar = value.charAt(0);
Result result;
if (startChar == FOUR || startChar == SEVEN) {
result = getStartWith4Or7(value);
} else {
result = getNotStartWith4Or7(value);
}
System.out.println("Final value is : " + result.getValue());
}
private static Result getNotStartWith4Or7(String value) {
Result result = new Result();
char startChar = value.charAt(0);
if (startChar < FOUR) {
result.value = value.replaceAll(".", String.valueOf(FOUR));
} else if (startChar > SEVEN) {
result.value = value.replaceAll(".", String.valueOf(FOUR));
result.flag = FOUR;
} else if (startChar > FOUR && startChar < SEVEN) {
result.value = getSubString(value).replaceAll(".", String.valueOf(FOUR));
result.value = String.valueOf(SEVEN) + result.value;
}
return result;
}
private static Result getStartWith4Or7(String value) {
Result result = new Result();
if (value != null && !value.equalsIgnoreCase("")) {
char startChar = value.charAt(0);
if (startChar == FOUR || startChar == SEVEN) {
value = getSubString(value);
result = getStartWith4Or7(value);
result.value = getStartCharUpdate(startChar, result) + result.value;
} else {
result = getNotStartWith4Or7(value);
}
}
return result;
}
private static String getStartCharUpdate(char startChar, Result result) {
String newValue = String.valueOf(startChar);
if (result.flag == FOUR) {
if (startChar == FOUR) {
newValue = String.valueOf(SEVEN);
result.flag = 0;
} else {
newValue = String.valueOf(FOUR);
}
}
return newValue;
}
private static String getSubString(String value) {
int len = value.length();
String finalValue = "";
if (len > 1) {
finalValue = value.substring(1, len);
}
return finalValue;
}
static class Result {
String value = "";
char flag;
public String getValue() {
if (flag == FOUR) {
value = FOUR + value;
}
return value;
}
}
}
*
You can try something like this.
String num = "4476";
double immediateVal = 0;
int length = num.length();
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
for (int i = 0; i < length; i++) {
sb1.append("4");
sb2.append("7");
}
double valNum = Double.parseDouble(num);
double val1 = Double.parseDouble(sb1.toString());
double val2 = Double.parseDouble(sb2.toString());
if (valNum < val1) {
immediateVal = val1;
} else if (val1 <= valNum && valNum < val2) {
if(num.indexOf("4")==0){
int firstIndexOf7=-1;
for(int a=0;a<length;a++){
firstIndexOf7=num.indexOf("7");
if(firstIndexOf7!=-1){
break;
}
}
if(firstIndexOf7!=-1){
StringBuilder sb3=new StringBuilder();
for(int b=0;b<firstIndexOf7;b++){
sb3.append("4");
}
for(int b=firstIndexOf7;b<length;b++){
sb3.append("7");
}
immediateVal=Double.parseDouble(sb3.toString());
}
} else{
immediateVal = val2;
}
}else if(valNum>=val2){
immediateVal=Double.parseDouble(sb1.append("4").toString());
}
System.out.println(immediateVal);
this can help you
static String toOutput(String input){
char[] values = input.toCharArray();
StringBuilder result = new StringBuilder();
int length = values.length;
int currentPosition = 0;
for(char current: values){
Integer currentInt = new Integer(current);
if(currentInt<4){
//fill the string with 4, best result
for(currentPosition;currentPosition<length;currentPosition++){
result.append(4);
}
break;
}
else if(currentInt==4){
result.append(4);
currentPosition++;
continue;
}
else if(currentInt<=7){
result.append(7);
currentPosition++;
continue;
}
else if(currentInt>7){
if(currentPosition=0){
//fill the string with 4 but with length +1, best result
for(currentPosition;currentPosition<=length;currentPosition++){
result.append(4);
}
break;
}
else{
// you need work this case, change last 4 to 7 and fill the rest with 4. enjoy it.
}
}
return result.toString();
}
One approach would be reading the digits right to left and check if that is less than 4 or 7 and add 4 or 7 respectively.
One optimization would be check if first(from left) digit is >7 then its sure that you will have all 4's +1 extra 4`.
You need to take extra care at the left most digit. If the left most digit is greater than 7 you need to add two 4s.
EX: 1234
right to left `4` is `4`
`3` is `4`
`2` is `4`
`1` is `4`
This approach wont work if all the digits in the number are 4 or 7. You need to have one condition and change one or two chars accordingly.
private static String toOutput(int a) {
String s = Integer.toString(a);
StringBuilder sb = new StringBuilder();
if (Integer.valueOf(s.charAt(0)) > 7) {
for(int i=0; i<= s.length(); i++) {
sb.append("4");
}
return sb.toString();
}
for(int i=s.length()-1; i>=0; i--) {
Integer x = Integer.valueOf(i);
if(x <=4) {
sb.append(4);
} else {
sb.append(7);
}
}
return sb.reverse().toString();
}
This is not checking if the number has all 4's or 7's.
I don't think you need to worry about performance for converting a number into a String. You're evaluating a number as if it's a string, so it only makes sense to cast it to string to do the evaluation.
Something like this works and is reasonably fast.
public static int closestNumber(int num) {
for (int i = num + 1; i < Integer.MAX_VALUE; i++) {
if ((i+"").matches("^[47]+$")) {
return i;
}
}
throw new RuntimeException("Your number was too close to Integer's max value!");
}
Ok, I wrote it using mod and no strings:
public static int closestNumber(int num) {
for (int i = num + 1; i < Integer.MAX_VALUE; i++) {
if (containsOnly(i,4,7)) {
return i;
}
}
throw new RuntimeException("Your number was too close to Integer's max value!");
}
public static boolean containsOnly(int evaluate, int numeralA, int numeralB) {
while (evaluate > 0) {
int digit = evaluate % 10;
if (digit != numeralA && digit != numeralB) return false;
evaluate = evaluate / 10;
}
return true;
}
It looks like looking for the first digit that is not 4 or 7 counting from left to right.
Set up a index pointer to record the last index that hold digit "4" and check every digit from left to right.
Initial current pointer index (c) to -1 and set last "4" index (l) to -1
For every digit from left to right
update c (c+=1)
check digit value
digit = 7 -> do nothing
digit = 4 -> l = c
digit < 4 -> this digit change to "4", all remaining digits sets to "4", end check
4 < digit < 7 -> this digit change to "7", all remaining digits sets to "4", end check
digit > 7 -> do necessary change and end check
l = -1 => 444....444 (no. of digit = n+1)
l > -1 => digit at l change to "7", all digits after l change to "4"
Idea
For a n-digit value, if it contains only "4" or "7", you do nothing.
Then, if there is any non "4" or "7", what should it be?
Analyzing the pattern, we need to know the first occurrence of non "4"/"7" digit (from left to right) only and all digits after the digit will change to "4" to minimize the value since 444...444 is the least k-digit value for combination of "4" and "7" for all k.
Consider case Xcccccccc , c is any value
If X in {4,7}, consider case 2.
If X in {1,2,3}, the next value should be 444444444.
If X in {5,6}, the next value should be 744444444.
If X in {8,9}, the next value should be 4444444444
Consider case aaaaXcccc, if a are "4" or "7"
If X in {4,7}, consider case aaaaaXccc.
If X in {0,1,2,3}, the next value should be aaaa44444.
If X in {5,6}, the next value should be aaaa74444.
If X in {8,9}, the next value should be bbbb44444 or bbbbb44444.(b are "4" or "7")
then how to deduce bbbb or bbbbb?
if aaaa does not have any "4", you get bbbbb = 44444 (since aaaa=7777)
if aaaa have "4", you get bbbb ("4" will be replaced by "7", e.g. 474779 => 477444)
Consider case aaaaaaaaX, this should be same as case 2 except no remaining digit need to be handle
Combine case 1-3, when the first occurrence of non "4"/"7" digit is in {8,9}, the difference in change of value depends on whether there is any "4" before the digit.
String message= "10";
byte[] bytes = message.getBytes();
for (int n = 0; n < bytes.length; n++) {
byte b = bytes[n];
for (int i = 0; i < 8; i++) {//do something for each bit in my byte
boolean bit = ((b >> (7 - i) & 1) == 1);
}
}
My problem here is that it takes 1 and 0 as their ASCII values, 49 and 48, instead of 1 and 0 as binary(00000001 and 00000000). How can I make my program treat each character from my string as a binary sequence of 8 bits?
Basicly, I want to treat each bit of my number as a byte. I do that like this byte b = bytes[n]; but the program treats it as the ASCII value.
I could assign the number to an int, but then, I can't assign the bits to a byte.
It's a bit messy, but the first thing that comes to mind is to first, split your message up into char values, using the toCharArray() method. Next, use the Character.getNumericValue() method to return the int, and finally Integer.toBinaryString.
Example
String message = "123456";
for(char c : message.toCharArray())
{
int numVal = Character.getNumericValue(c);
String binaryString = Integer.toBinaryString(numVal);
for(char bit : binaryString)
{
// Do something with your bits.
}
}
String msg = "1234";
for(int i=0 ; i<msg.length() ; i++ ){
String bits = Integer.toBinaryString(Integer.parseInt(msg.substring(i, i+1)));
for(int j=0;j<8-bits.length();j++)
bits = "0"+bits;
}
Now bits is a string of length 8.
1
00000001
10
00000010
11
00000011
100
00000100
You can use getBytes() on the String
Use Java's parseInt(String s, int radix):
String message= "10";
int myInt = Integer.parseInt(message, 2); //because we are parsing it as base 2
At that point you have the correct sequence of bits, and you can do your bit-shifting.
boolean[] bits = new boolean[message.length()];
System.out.println("Parsed bits: ");
for (int i = message.length()-1; i >=0 ; i--) {
bits[i] = (myInt & (1 << i)) != 0;
System.out.print(bits[i] ? "1":"0");
}
System.out.println();
You could make it bytes if you really want to, but booleans are a better representation of bits...