Java for loop i++ as a string - java

Let's say we have a for loop
for(int i = 0; i < 10; i++) {
...
}
What format is the i++ in?
I have a String increment = "i++" which tells me how much to increment i by.
But when I just directly try and put the increment string as an incrementor it doesn't work. I tried the below but it doesn't work.
for(int i = 0; i < 10; increment) {
...
}
How can I make this work?

The increment need to be an direct attribution,
you can't use a String to define this, is impossible
One solution to change dynamically how much will be the increment, it's using a variable
int j=1;
for(int i=0;i<10;i+=j)
the += operator it's used for the increment, for example:
int x = 0;
x += 1; //x is 1
x += 3; //x is 4
x += 2; //x is 6
x++; //x is 7
But in the most cases you don't need to use this in a for loop, what you need to do?
Hugs

You could parse the increment string to an int then use that as your increment in your loop:
String increment = "i+2"; // Will also work for "i++" or "i+n" (n = a number)
String num = increment.replaceAll("i\\+*", "");
int incValue = 1;
if(!num.isEmpty())
incValue = Integer.parseInt(num);
for(int i = 0; i < 10 ; i+=incValue)
{
System.out.println(i);
}

So for this, you cannot use a string as a expression.
There will be quite a few ways to map a String to expression.
One of the ways is you can use switch case:
String increment = "i++";
int i = 0;
while(i < 10)
{
//your logic here
switch (increment){
case "i++":
i++;
break;
case "i=i+2":
i = i + 2;
break;
}
}
You can also use Regex or parse the String to convert to int

You can simply get increment count in a string if you want to do increment dynamically, instead of whole increment statement. Here is an example:
String inc = "2";
String max = "10";
for(int i = 0; i < Integer.valueOf(max); i=i+Integer.valueOf(inc)) {
System.out.println(i);
}

i++ is just code : it's not a string as you thought.
Here's an analogy to demonstrate your assumption:
String someString =
"public static void doStuff()
{
System.out.println("this is working");
}";
Now if you refer to the String someString in a separate method, do you think that the doStuff() method will be called? Of course not, because String is just text that the interpreter doesn't go through. The interpreter can only go through executable code, which includes the i++ in question.

Related

How to find frequency of characters in a string without using array in java

Given a String, I want to create a frequency distribution of characters in the String. That is, for each distinct character in the string, I want to count how many times it occurs.
Output is a String that consists of zero or more occurrences of the pattern xd, where x is a character from the source String, and d is the number of occurrences of x within the String. Each x in the output should occur once.
The challenge is to do this without using an array or Collection.
Examples:
Source: "aasdddr" Result: "a2s1d3r1"
Source: "aabacc" Result: "a3b1c2"
Source: "aasdddraabcdaa" Result: "a6s1d4r1b1c1"
I tried this way:
String str = "aasdddr", result = "";
int counter = 0;
for(int i = 0; i < str.length(); i++){
result += "" + str.charAt(i);
for(int j = 1; j < str.length(); j++){
if(str.charAt(i) == str.charAt(j)){
counter++;
}
}
result += counter;
}
System.out.println(result);
My output is a1a2s3d6d9d12r13
Finally, I found the solution. But I think any question has more than one solution.
First, we should declare an empty string to keep the result. We use a nested loop because the outer loop will keep a character fixed during each iteration of the inner loop. Also, we should declare a count variable inside the outer loop. Because in each match, it will be increased by one and after controlling each character in the inner loop, it will be zero for the next check. Finally, after the inner loop, we should put a condition to check whether we have that character inside the result string. If there isn't any character like that, then it will be added to the result string. After that, its frequency (count) will be added. Outside of the loop, we can print it.
public class FrequenciesOfChar {
public static void main(String[] args) {
String str = "aabcccd"; // be sure that you don't have any digit in your string
String result = ""; // this will hold new string
for (int i = 0; i < str.length(); i++) { // this will hold a character till be checked by inner loop
int count = 0; // put here so that it can be zero after each cycle for new character
for (int j = 0; j < str.length(); j++) { // this will change
if(str.charAt(i) == str.charAt(j)){ // this will check whether there is a same character
count++; // if there is a same character, count will increase
}
}
if( !(result.contains(""+str.charAt(i))) ){ // this checks if result doesn't contain the checked character
result += ""+str.charAt(i); // first if result doesn't contain the checked character, character will be added
result += count; // then the character's frequency will be added
}
}
System.out.println(result);
}
}
Run Result:
aabcccd - a2b1c3d1
First, counter needs to be reset inside the for loop. Each time you encounter a character in the source String, you want to restart the counter. Otherwise, as you have seen, the value of the counter is strictly increasing.
Now, think about what happens if a character occurs in more than one place in the source String, as in the "aasdddraabcdaa" example. A sequence of 1 or more a appears in 3 places. Because, at the time you get to the 2nd occurrence of a, a has been previously counted, you want to skip over it.
Because the source String cannot contain digits, the result String can be used to check if a particular character value has already been processed. So, after fixing the problem with counter, the code can be fixed by adding these two lines:
if (result.indexOf (source.charAt(i)) >= 0) {
continue; }
Here is the complete result:
package stackoverflowmisc;
public class StackOverflowMisc {
public static String freqDist(String source) {
String result = "";
int counter ;
for (int i = 0; i < source.length(); i++) {
if (result.indexOf (source.charAt(i)) >= 0) { continue; }
counter = 1;
result += source.charAt(i);
for (int j = 1; j < source.length(); j++) {
if (source.charAt(i) == source.charAt(j)) {
counter++;
}
}
result += counter;
}
return result;
}
public static void main(String[] args) {
String [] test = {"aasdddr", "aabacc", "aasdddraabcdaa"};
for (int i = 0; i < test.length; ++i) {
System.out.println (test[i] + " - " + freqDist (test[i]));
}
System.out.println ("End of Program");
}
}
Run results:
aasdddr - a2s2d4r2
aabacc - a3b2c3
aasdddraabcdaa - a6s2d5r2b2c2
End of Program
In one of the Q&A comments, you said the source string can contain only letters. How would the program work if it were allowed to contain digits? You can't use the result String, because the processing inserts digits there. Again, this is an easy fix: Add a 3rd String to record which values have already been found:
public static String freqDist2(String source) {
String result = "", found = "";
int counter ;
for (int i = 0; i < source.length(); i++) {
if (found.indexOf (source.charAt(i)) >= 0) { continue; }
counter = 1;
result += source.charAt(i);
found += source.charAt(i);
for (int j = 1; j < source.length(); j++) {
if (source.charAt(i) == source.charAt(j)) {
counter++;
}
}
result += counter;
}
return result;
}
Another possibility is to delete the corresponding characters from the source String as they are counted. If you are not allowed to modify the Source String, make a copy and use the copy.
Comment: I don't know if this is what your professor or whomever had in mind by placing the "No array" restriction, because a String is essentially built on a char array.

Algorithm for combinatorics (6 choose 2)

Following this question, I want to now code "6 choose 2" times "4 choose 2." By that I mean, lets say I have 6 characters "A B C D E F." The first time I choose any two characters to delete. The 2nd time I want to choose 2 different letters to delete and then I append the results of these two trials. Hence, I will receive 90("6 choose 2" times "4 choose 2") eight character strings. The characters in the pattern are from the same pattern {1,2,3,4,5, 6}. All the characters are unique and no repetition.
Here is what I have so far.
public String[] genDelPatterns(String design){
char[] data = design.toCharArray();
String[] deletionPatterns = new String[15];
int x = 0;
StringBuilder sb = new StringBuilder("");
int index = 0;
for(int i = 0; i < (6-1); i++){
for(int j = i+1; j < 6; j++){
for(int k= 0; k < 6; k++){
if((k != j) && (k != i))
sb.append(String.valueOf(data[k]));
}
deletionPatterns[x++] = sb.toString();
sb = new StringBuilder("");
}
}
return deletionPatterns;
}
public String[] gen8String(String[] pattern1, String[] pattern2){
String[] combinedPatterns = new String[225];
int k = 0;
for(int i = 0; i < 15; i++)
{
for(int j = 0; j < 15; j++)
combinedPatterns[k++] = pattern1[i] + pattern2[j];
}
return combinedPatterns;
}
I will be calling the methods like this:
gen8String(genDelPatterns("143256"), genDelPatterns("254316"));
Currently, I am generating all the possible 8 letter strings. But I want to only generate the 8 character strings according to the aforementioned specifications. I am really stuck on how I can elegantly do this multiplication. The only way I can think of is to make another method that does "4 choose 2" and then combine the 2 string arrays. But this seems very roundabout.
EDIT: An example of an 8 character string would be something like "14322516", given the inputs I have already entered when calling gen8String, (143256,254316). Note that the first 4 characters are derived from 143256 with the 5 and 6 deleted. But since I deleted 5 and 6 in the first trail, I am no longer allowed to delete the same things in the 2nd pattern. Hence, I deleted the 3 and 4 from the 2nd pattern.
you have a chain of methods , each one called a variation itself.
For so, my advice is to use a recursive method!
to achieve your goal you have to have a little experience with this solution.
A simple example of a method that exploits the recursion:
public static long factorial(int n) {
if (n == 1) return 1;
return n * factorial(n-1);
}
I can also suggest you to pass objects (constructed to perfection) for the method parameter, if is too complex to pass simple variables
This is the heart of this solution in my opinion.
While what you tried to do is definitely working, it seems you are looking for other way to implement it. Here is the skeleton of what I would do given the small constrains.
// Very pseudo code
// FOR(x,y,z) := for(int x=y; x<z;x++)
string removeCharacter(string s, int banA, int banB){
string ret = "";
FOR(i,1,7){
if(i != banA && i != banB){
ret += s[i];
}
}
return ret;
}
List<string> Generate(s1,s2){
List<string> ret = new List<string>();
FOR(i,1,7) FOR(j,i+1,7) FOR(m,1,7) FOR(n,m+1,7){
if(m != i && m != j && n != i && n != j){
string firstHalf = removeCharacter(s1,i,j);
string secondHalf = removeCharacter(s2,m,n);
ret.Add(firstHalf + secondHalf);
}
}
return ret;
}
This should generate all possible 8-characters string.
Here is the solution I came up with. Doesn't really take "mathematical" approach, I guess. But it does the job.
//generating a subset of 90 eight character strings (unique deletion patterns)
public static String[] gen8String(String[] pattern1, String[] pattern2){
String[] combinedSubset = new String[90]; //emty array for the subset of 90 strings
String combinedString = ""; //string holder for each combined string
int index = 0; //used for combinedSubset array
int present = 0; //used to check if all 6 characters are present
for(int i = 0; i < 15; i++){
for(int j = 0; j < 15; j++){
combinedString = pattern1[i] + pattern2[j]; //combine both 4 letter strings into 8 char length string
char[] parsedString = combinedString.toCharArray(); //parse into array
//check if all 6 characters are present
for(int k = 1; k <= 6; k++)
{
if(new String(parsedString).contains(k+"")) {
present++;
}
else
break;
//if all 6 are present, then add it to combined subset
if(present == 6)
combinedSubset[index++] = combinedString;
}
present = 0;
}
}
return combinedSubset;
}

Doesn't enter in the "for-loop"?

Here is my code :
private String SerialNo;
private String FirmVersion;
public String GetSerial(int[] Data){
System.out.println("GetSerial Debug : Data => "+Data);
for (int i = 2;i==13;i++){
System.out.println("In the FOR => ok ");
if (i != 9){
SerialNo = SerialNo + Data[i];
}
if (i == 9){
SerialNo = SerialNo + ".";
}
}
System.out.println("SerialNo => "+ SerialNo);
return SerialNo;
}
My problem : I can't "enter" in the FOR
So my sysout of "In the FOR => ok", never shows and all the "actions" aren't done.
What am I doing wrong ?
ps : I'm sure that I'm compiling the right file.
The loop condition is never satisfied; i = 2 in the begin, the first check would fail, so all the loop would fail. Maybe it should be changed for:
for (int i = 2; i <= 13; ++i)
Examine your for statement:
for (int i = 2; i==13; i++)
This actually means the following:
assign 2 to i
Check whether i equal to 13. If yes, continue loop, exit otherwise.
Since i is not 13 in the first iteration of loop you never enter it. I believe that you wanted to write
for (int i = 2; i <= 13; i++)
In this case you will iterate from 2 to 13 inclusively. The condition of for loop means "do I have to remain iterating?" and not "do I have to escape?"
Change for (int i = 2; i == 13; i++) to for (int i = 2; i <= 13; i++).
The second argument is the loop condition which has to be true to run the loop.
Your condition became false at first iteration so control never goes to loop body.
for loop syntax:
for(initialization; condition; increment/ decrement){
//your code
}
So here you will have to use some appropriate condition to enter into the loop.
So for example :
for (int i = 0; i <= 13; i++) // for 0 to 13 increment
or
for (int i = 10; i >= 0; i--) // for 10 to 0 decrement
for (int i = 2;i==13;i++){}
It enters but failed at first condition check and for-loop exits.
It should be -
for (int i = 2;i<=13;i++)
You have initialized i=2
for (int i = 2;i==13;i++)
And condition is i==13 which will become false ultimately flow never enter into for loop
try to change the code like this
for (int i = 2;i<=13;i++)
Statement is not good should be like the one below:
for (int i = 2; i<13; i++) or for (int i = 2; i<=13; i++)
See compared simple while loop in the case of your for loop.
Think about int i =2; value set and i == 13 condition
Do you think it will work?
for (int i = 2;i==13;i++){
//do something
}
Same to below *while loop* explanation
int i = 2;
while (i == 13) {
//do something
i++;
}
I am sure it will work
for (int i = 2;i < 13;i++){
//do something
}
Same to below **while loop**
int i = 2;
while (i < 13) {
//do something
i++;
}
The flow of the for loop is: init statement-> condition check-> goes inside loop or outside depending on the condition outcome.
Here, since you've said i=2 ,then i==13 is false; it'll never go inside the loop.
You could use the ?: operator in the for loop and then modify your if statements a bit I guess..

Java: Longest Ascending substring

I am trying to create a Java program that reads a numerical string typed from the keyboard,
and gives out the longest ascending substring.
The following is my code:
import java.util.Scanner;
public class Ascending{
public static void main(String args[]){
Scanner in = new Scanner(System.in);
System.out.print("Enter a number = ");
String n = in.nextLine();
int length = n.length();
for(int i = 0; i < length; i++) {
char first = n.charAt(i);
char next = n.charAt(i+1);
char last = n.charAt(length-1);
int f = (int)(first - 48);
int nx = (int)(next - 48);
int l = (int)(last - 48);
if (f<nx) {
String asc = n.substring(i, i++);
i++;
System.out.println("output = " + asc);
}
else {
String asc = n.substring(i, i++);
System.out.println("output = " + asc);
break;}
}
}
}
When I compile the above, I get
<Enter a number = 12 output = >
without any results.
I am assuming something went wrong inside the for-loop but I am unable to figure out where exactly I went wrong.
I'm afraid I might have defined too many unnecessary variables?
You are using the post-increment operator, but I don't think you have experimented to see how it works. Try this:
int i = 0;
System.out.println(i);
System.out.println(i++);
System.out.println(i);
You'll get
0
0
1
That's because post-increment (++) says "increment this value, then return what the value was before you incremented it".
So when you ask for
n.substring(i, i++);
You are explicitly asking for a 0-length string (because i == i++).
You could use the pre-increment operator, ++i, but it's rarely used outside of code-golf so you'll just end up confusing people. Best practice IMO is to just use ++ on its own line and avoid looking at the return value.
Really, what you want here is
n.substring(i, i+1);

Reduce String.charAt to one loop during String comparison

I need to compare two strings that are of varying length and as such I have written two conditional loops depending on which String is longest:
boolean compare(String first, String second)
{
boolean firstLongest = first.length() > second.length();
if(firstLongest)
{
for(int i = 0; i < first.length(); i++)
//charAt code here
}
else{
for(int i = 0; i < second.length();i++)
//charAt code here
}
}
I decided to re-write it as so:
boolean compare(String first, String second)
{
int lengthDifference = first.length() - second.length();
for(int i = 0; i < first.length() + lengthDifference;i++)
//charAt code here
}
I want to avoid having 1) two loops and 2) out of bounds exceptions. My question is does the above implementation have a corner case that I am missing or should this work for all possible inputs.
Your revised version will break if the second string is longer.
Use:
int combinedLength = Math.min(first.length(), second.length());
then your condition only needs to be:
i < combinedLength
Simply use the lowest one:
//Maybe knowing what the length diff is interesting to achieve your goal:
int lenDiff = Math.abs(first.length() - second.length());
// The loop, taking the length of the shortest one as limit
for (int i = 0; i < Math.min(first.length(), second.length()); ++i)
{
// Char code here
}

Categories

Resources