I am writing a code in android for rpn calculations and it crashes when i have operators inside brackets. Eg(89+7) crashes but (8)+7 outputs 15.
This is the method i use for infix to postfix conversion:
private static List<String> convert(String input) {
int p = 0;
String pfb = "";
Stack<Character> chara = new Stack<>();
List<String> pfa = new ArrayList<>();
for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
if (pfb.length() > 0) {
pfa.add(pfb);
}
pfb = "";
if (chara.empty()) {
chara.push(ch);
} else {
Character chTop = (Character) chara.peek();
if (chTop == '*' || chTop == '/')
p = 1;
else if (chTop == '+' || chTop == '-')
p = 0;
if (p == 1) {
if (ch == '+' || ch == '-') {
pfa.add(String.valueOf(chara.pop()));
i--;
Log.d("pfa", "" + input.length() + "" + i);
} else { // Same
pfa.add(String.valueOf(chara.pop()));
i--;
}
} else {
if (ch == '+' || ch == '-' && chara.peek() != '(') {
pfa.add(String.valueOf(chara.pop()));
chara.push(ch);
} else
chara.push(ch);
}
}
} else if (ch == '(') {
chara.push(ch);
// Log.d("St",""+chara.peek());
} else if (ch == ')') {
`//Code crashes here` while (chara.peek() != '(' && !chara.empty()) {
pfa.add(String.valueOf(chara.pop()));
}
if (!chara.empty() && chara.peek() != '(')
return null; // invalid expression
else
chara.pop();
} else {
pfb += ch;
}
// Log.d("pfa",""+pfa+"");
}
return pfa;
}
You code crashes because first you peek the stack element and then checking the empty condition.
it should be like
while ( !chara.empty() && chara.peek() != '(' )
Related
I made a code to show the amount of times a vowel is used. A, E, I, O, U. The code is counting but it is not conunting correctly.
#Override
public void onClick(View v) {
int letter1 = 0;
int letter2 = 0;
String enter1 = str1.getText().toString();
String enter2 = str2.getText().toString();
for (int i = 0; i < str1.length(); i++) {
if (enter1.charAt(i) == 'a' || enter1.charAt(i) == 'e' || enter1.charAt(i) == 'i' || enter1.charAt(i) == 'o' ||
enter1.charAt(i) == 'u')
{
letter1++;
}
for(int j = 0; j < str2.length(); j ++){
if(enter2.charAt(j) == 'a' || enter2.charAt(j) == 'e' || enter2.charAt(j) == 'i' || enter2.charAt(j) == 'o' ||
enter2.charAt(j) == 'u')
{
letter2++;
}
}
display3.setText("The amount of vowels are :"+ letter1 + " & " + letter2);
}
}
});
My output for Hello World is 2 and 5. 2 for Hello is correct but 5 for World is not. What am I missing?
If we reformat the code slightly, the problem is more apparent:
for (int i = 0; i < str1.length(); i++) {
if (enter1.charAt(i) == 'a' || enter1.charAt(i) == 'e' || enter1.charAt(i) == 'i' || enter1.charAt(i) == 'o' ||
enter1.charAt(i) == 'u') {
letter1++;
}
for (int j = 0; j < str2.length(); j++) {
if (enter2.charAt(j) == 'a' || enter2.charAt(j) == 'e' || enter2.charAt(j) == 'i' || enter2.charAt(j) == 'o' ||
enter2.charAt(j) == 'u') {
letter2++;
}
}
display3.setText("The amount of vowels are :" + letter1 + " & " + letter2);
}
As you can see, the second for loop is inside the first one. That means the second number will be N times larger than it should be, where N is the length of the first word. This matches what's happening: there is only 1 vowel in "world" but there are 5 letters in "hello".
The display3.setText(...) part will also be executed N times, but since it overwrites the previous value you won't be able to notice that, and you'll just see the final value.
To fix, just close the first for loop earlier:
for (int i = 0; i < str1.length(); i++) {
if (enter1.charAt(i) == 'a' || enter1.charAt(i) == 'e' || enter1.charAt(i) == 'i' || enter1.charAt(i) == 'o' ||
enter1.charAt(i) == 'u') {
letter1++;
}
}
for (int j = 0; j < str2.length(); j++) {
if (enter2.charAt(j) == 'a' || enter2.charAt(j) == 'e' || enter2.charAt(j) == 'i' || enter2.charAt(j) == 'o' ||
enter2.charAt(j) == 'u') {
letter2++;
}
}
display3.setText("The amount of vowels are :" + letter1 + " & " + letter2);
Something problem with the brackets
#Override
public void onClick(View v) {
for(Loop){
if(condition){
}
}//first loop
for(Loop){
if(condition){
}
}//second loop
//display here
});//end for onClick
Things is Working:
The format (XXX-XXX-XXXX) which I want in phone number EditText is worked.
Problem is:
While deleting character "-" ,It can't deleted. I am getting stuck.
PhoneNumberTextWatcher.java
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
public class PhoneNumberTextWatcher implements TextWatcher {
private static final String TAG = PhoneNumberTextWatcher.class
.getSimpleName();
private EditText edTxt;
public boolean isDelete;
public PhoneNumberTextWatcher(EditText edTxtPhone) {
this.edTxt = edTxtPhone;
edTxt.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.KEYCODE_DEL) {
isDelete = true;
LogUtils.Log_e("ISDELETE", String.valueOf(isDelete));
}
return false;
}
});
}
l.substring(6, val.length());
} else if (val.length() > 3 && val.length() < 6) {
b = val.substring(3, val.length());
}
StringBuffer stringBuffer = new StringBuffer();
if (a != null && a.length() > 0) {
stringBuffer.append(a);
if (a.length() == 3) {
stringBuffer.append("-");
}
}
if (b != null && b.length() > 0) {
stringBuffer.append(b);
if (b.length() == 3) {
stringBuffer.append("-");
}
}
if (c != null && c.length() > 0) {
stringBuffer.append(c);
}
edTxt.removeTextChangedListener(this);
edTxt.setText(stringBuffer.toString());
edTxt.setSelection(edTxt.getText().toString().length());
edTxt.addTextChangedListener(this);
} else {
edTxt.removeTextChangedListener(this);
edTxt.setText("");
edTxt.addTextChangedListener(this);
}
}
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void afterTextChanged(Editable s) {
LogUtils.Log_e("ISDELETE", String.valueOf(isDelete));
if (isDelete) {
isDelete = false;
return;
}
LogUtils.Log_e("ISDELETE", String.valueOf(isDelete));
String val = s.toString();
String a = "";
String b = "";
String c = "";
if (val != null && val.length() > 0) {
val = val.replace("-", "");
if (val.length() >= 3) {
a = val.substring(0, 3);
} else if (val.length() < 3) {
a = val.substring(0, val.length());
}
if (val.length() >= 6) {
b = val.substring(3, 6);
c = val.substring(6, val.length());
} else if (val.length() > 3 && val.length() < 6) {
b = val.substring(3, val.length());
}
StringBuffer stringBuffer = new StringBuffer();
if (a != null && a.length() > 0) {
stringBuffer.append(a);
if (a.length() == 3) {
stringBuffer.append("-");
}
}
if (b != null && b.length() > 0) {
stringBuffer.append(b);
if (b.length() == 3) {
stringBuffer.append("-");
}
}
if (c != null && c.length() > 0) {
stringBuffer.append(c);
}
edTxt.removeTextChangedListener(this);
edTxt.setText(stringBuffer.toString());
edTxt.setSelection(edTxt.getText().toString().length());
edTxt.addTextChangedListener(this);
} else {
edTxt.removeTextChangedListener(this);
edTxt.setText("");
edTxt.addTextChangedListener(this);
}
}
}
I am trying TextWatcher using below code:
edtOrderCardPhone.addTextChangedListener(new PhoneNumberTextWatcher(edtOrderCardPhone));
See related question here.
Can any one help to solve problem!
I found solution to change my PhoneNumberTextWatcher using below code.
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
public class PhoneNumberTextWatcher implements TextWatcher {
private static final String TAG = "PhoneNumberTextWatcher";
private EditText editText;
public PhoneNumberTextWatcher(EditText edTxtPhone) {
this.editText = edTxtPhone;
}
public void onTextChanged(CharSequence s, int cursorPosition, int before,
int count) {
if (before == 0 && count == 1) { //Entering values
String val = s.toString();
String a = "";
String b = "";
String c = "";
if (val != null && val.length() > 0) {
val = val.replace("-", "");
if (val.length() >= 3) {
a = val.substring(0, 3);
} else if (val.length() < 3) {
a = val.substring(0, val.length());
}
if (val.length() >= 6) {
b = val.substring(3, 6);
c = val.substring(6, val.length());
} else if (val.length() > 3 && val.length() < 6) {
b = val.substring(3, val.length());
}
StringBuffer stringBuffer = new StringBuffer();
if (a != null && a.length() > 0) {
stringBuffer.append(a);
}
if (b != null && b.length() > 0) {
stringBuffer.append("-");
stringBuffer.append(b);
}
if (c != null && c.length() > 0) {
stringBuffer.append("-");
stringBuffer.append(c);
}
editText.removeTextChangedListener(this);
editText.setText(stringBuffer.toString());
if (cursorPosition == 3 || cursorPosition == 7) {
cursorPosition = cursorPosition + 2;
} else {
cursorPosition = cursorPosition + 1;
}
if (cursorPosition <= editText.getText().toString().length()) {
editText.setSelection(cursorPosition);
} else {
editText.setSelection(editText.getText().toString().length());
}
editText.addTextChangedListener(this);
} else {
editText.removeTextChangedListener(this);
editText.setText("");
editText.addTextChangedListener(this);
}
}
if (before == 1 && count == 0) { //Deleting values
String val = s.toString();
String a = "";
String b = "";
String c = "";
if (val != null && val.length() > 0) {
val = val.replace("-", "");
if (cursorPosition == 3) {
val = removeCharAt(val, cursorPosition - 1, s.toString().length() - 1);
} else if (cursorPosition == 7) {
val = removeCharAt(val, cursorPosition - 2, s.toString().length() - 2);
}
if (val.length() >= 3) {
a = val.substring(0, 3);
} else if (val.length() < 3) {
a = val.substring(0, val.length());
}
if (val.length() >= 6) {
b = val.substring(3, 6);
c = val.substring(6, val.length());
} else if (val.length() > 3 && val.length() < 6) {
b = val.substring(3, val.length());
}
StringBuffer stringBuffer = new StringBuffer();
if (a != null && a.length() > 0) {
stringBuffer.append(a);
}
if (b != null && b.length() > 0) {
stringBuffer.append("-");
stringBuffer.append(b);
}
if (c != null && c.length() > 0) {
stringBuffer.append("-");
stringBuffer.append(c);
}
editText.removeTextChangedListener(this);
editText.setText(stringBuffer.toString());
if (cursorPosition == 3 || cursorPosition == 7) {
cursorPosition = cursorPosition - 1;
}
if (cursorPosition <= editText.getText().toString().length()) {
editText.setSelection(cursorPosition);
} else {
editText.setSelection(editText.getText().toString().length());
}
editText.addTextChangedListener(this);
} else {
editText.removeTextChangedListener(this);
editText.setText("");
editText.addTextChangedListener(this);
}
}
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void afterTextChanged(Editable s) {
}
public static String removeCharAt(String s, int pos, int length) {
String value = "";
if (length > pos) {
value = s.substring(pos + 1);
}
return s.substring(0, pos) + value;
}
}
Thanks B Bhanu Chander for solution.
You can do this way:
private EditText editText;
onCreate():
editText = (EditText) findViewById(R.id.editText);
editText.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
Screen shot:
Hope this will help you.
I have a list of numbers, in that list I want to check if any of the numbers match, and if so return 'true'. Essentially, what I want to check is if the numbers match, then do not save. I've gotten a seemingly very inefficient method to check. Any help would be appreciated, thanks!
if (mFav1Compare == mNumber1Compare || mFav1Compare == mNumber2Compare || mFav1Compare == mNumber3Compare || mFav1Compare == mNumber4Compare || mFav1Compare == mNumber5Compare) {
return true;
}
if (mFav2Compare == mNumber1Compare || mFav2Compare == mNumber2Compare || mFav2Compare == mNumber3Compare || mFav2Compare == mNumber4Compare || mFav2Compare == mNumber5Compare) {
return true;
}
if (mFav3Compare == mNumber1Compare || mFav3Compare == mNumber2Compare || mFav3Compare == mNumber3Compare || mFav3Compare == mNumber4Compare || mFav3Compare == mNumber5Compare) {
return true;
}
if (mFav4Compare == mNumber1Compare || mFav4Compare == mNumber2Compare || mFav4Compare == mNumber3Compare || mFav4Compare == mNumber4Compare || mFav4Compare == mNumber5Compare) {
return true;
}
if (mFav5Compare == mNumber1Compare || mFav5Compare == mNumber2Compare || mFav5Compare == mNumber3Compare || mFav5Compare == mNumber4Compare || mFav5Compare == mNumber5Compare) {
return true;
}
If you have two lists and you want to know if the second list contains at least one element of the first list you could try
public <T> boolean listMatches(List<T> list1, List<T> list2) {
for (T element : list1) {
if (list2.contains(element)) {
return true;
}
}
return false;
}
Do you thought this?
ArrayList<Integer>listNumbers = new ArrayList<>();
listNumbers.add(99);
listNumbers.add(99);
listNumbers.add(11);
listNumbers.add(10);
for(int i = 0; i < listNumbers.size(); i++){
if(!listCheck(listNumbers.get(i))){
//save something
}
}
and this method
private boolean listCheck(int number){
for(int i = 0; i < listNumbers.size(); i++){
if(number == listNumbers.get(i)){
return true;
}
}
return false;
}
I'm trying to use the intent anchor to launch my app as described here. I'm able to get it to launch my app using this syntax,
Launch my app
but I have no idea what many of the various elements mean.
The basic syntax for an intent-based URI is as follows:
intent:
HOST/URI-path // Optional host
#Intent;
package=[string];
action=[string];
category=[string];
component=[string];
scheme=[string];
end;
what do each of the segments mean (so I know how I may best use take advantage of them)
how/where can I include any extra data (ie, my own parameters)
Here is the method toUri() from the Intent class:
public String toUri(int flags) {
StringBuilder uri = new StringBuilder(128);
String scheme = null;
if (mData != null) {
String data = mData.toString();
if ((flags&URI_INTENT_SCHEME) != 0) {
final int N = data.length();
for (int i=0; i<N; i++) {
char c = data.charAt(i);
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|| c == '.' || c == '-') {
continue;
}
if (c == ':' && i > 0) {
// Valid scheme.
scheme = data.substring(0, i);
uri.append("intent:");
data = data.substring(i+1);
break;
}
// No scheme.
break;
}
}
uri.append(data);
} else if ((flags&URI_INTENT_SCHEME) != 0) {
uri.append("intent:");
}
uri.append("#Intent;");
if (scheme != null) {
uri.append("scheme=").append(scheme).append(';');
}
if (mAction != null) {
uri.append("action=").append(Uri.encode(mAction)).append(';');
}
if (mCategories != null) {
for (String category : mCategories) {
uri.append("category=").append(Uri.encode(category)).append(';');
}
}
if (mType != null) {
uri.append("type=").append(Uri.encode(mType, "/")).append(';');
}
if (mFlags != 0) {
uri.append("launchFlags=0x").append(Integer.toHexString(mFlags)).append(';');
}
if (mPackage != null) {
uri.append("package=").append(Uri.encode(mPackage)).append(';');
}
if (mComponent != null) {
uri.append("component=").append(Uri.encode(
mComponent.flattenToShortString(), "/")).append(';');
}
if (mSourceBounds != null) {
uri.append("sourceBounds=")
.append(Uri.encode(mSourceBounds.flattenToString()))
.append(';');
}
if (mExtras != null) {
for (String key : mExtras.keySet()) {
final Object value = mExtras.get(key);
char entryType =
value instanceof String ? 'S' :
value instanceof Boolean ? 'B' :
value instanceof Byte ? 'b' :
value instanceof Character ? 'c' :
value instanceof Double ? 'd' :
value instanceof Float ? 'f' :
value instanceof Integer ? 'i' :
value instanceof Long ? 'l' :
value instanceof Short ? 's' :
'\0';
if (entryType != '\0') {
uri.append(entryType);
uri.append('.');
uri.append(Uri.encode(key));
uri.append('=');
uri.append(Uri.encode(value.toString()));
uri.append(';');
}
}
}
uri.append("end");
return uri.toString();
}
If you can read Java code then it should be pretty clear what is going on here. In any case, extras can be put in the URL and they look something like this:
<type>.<key>=<value>;
where <type> is one of the following:
S = String
B = Boolean
b = Byte
c = Character
d = Double
f = Float
i = Integer
l = Long
s = Short
Here are a few examples:
Launch app:
<a href="intent://#Intent;scheme=http;package=com.example.myapp;end">
Launch app with one String extra called "foo" containing the value "bar123":
<a href="intent://#Intent;scheme=http;package=com.example.myapp;S.foo=bar123;end">
Launch app with a String extra called "foo" containing the value "bar123" and an Integer extra called "number" containing the value "-567":
<a href="intent://#Intent;scheme=http;package=com.example.myapp;S.foo=bar123;i.number=-567;end">
As at android 28, the API has changed. Here is what the toUri code has been changed to:
public String toUri(#UriFlags int flags) {
StringBuilder uri = new StringBuilder(128);
if ((flags&URI_ANDROID_APP_SCHEME) != 0) {
if (mPackage == null) {
throw new IllegalArgumentException(
"Intent must include an explicit package name to build an android-app: "
+ this);
}
uri.append("android-app://");
uri.append(mPackage);
String scheme = null;
if (mData != null) {
scheme = mData.getScheme();
if (scheme != null) {
uri.append('/');
uri.append(scheme);
String authority = mData.getEncodedAuthority();
if (authority != null) {
uri.append('/');
uri.append(authority);
String path = mData.getEncodedPath();
if (path != null) {
uri.append(path);
}
String queryParams = mData.getEncodedQuery();
if (queryParams != null) {
uri.append('?');
uri.append(queryParams);
}
String fragment = mData.getEncodedFragment();
if (fragment != null) {
uri.append('#');
uri.append(fragment);
}
}
}
}
toUriFragment(uri, null, scheme == null ? Intent.ACTION_MAIN : Intent.ACTION_VIEW,
mPackage, flags);
return uri.toString();
}
String scheme = null;
if (mData != null) {
String data = mData.toString();
if ((flags&URI_INTENT_SCHEME) != 0) {
final int N = data.length();
for (int i=0; i<N; i++) {
char c = data.charAt(i);
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|| (c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+') {
continue;
}
if (c == ':' && i > 0) {
// Valid scheme.
scheme = data.substring(0, i);
uri.append("intent:");
data = data.substring(i+1);
break;
}
// No scheme.
break;
}
}
uri.append(data);
} else if ((flags&URI_INTENT_SCHEME) != 0) {
uri.append("intent:");
}
toUriFragment(uri, scheme, Intent.ACTION_VIEW, null, flags);
return uri.toString();
}
This shows that the chosen answer will no longer work.
Check this answer by David Wasser for a working solution.
I know this is probably one of dumbest questions ever but my brain seems off.
I have this method which makes a string out of vCard:
public static String process(String vCard) {
ArrayList<ArrayList<String>> vCardData = parseData(vCard);
if (vCardData != null) {
StringBuilder readableVCard = new StringBuilder();
for (int i = 0; i < FIELD_COUNT; i++) {
ArrayList<String> vCardDataField = vCardData.get(i);
if (vCardDataField.size() > 0) {
String field = null;
if (i == FORMATTED_NAME) {
field = "Name: ";
} else if (i == PHONE_MOBILE) {
field = "Phone (mobile): ";
} else if (i == PHONE_HOME) {
field = "Phone (home): ";
} else if (i == PHONE_WORK) {
field = "Phone (work): ";
} else if (i == PHONE) {
field = "Phone: ";
} else if (i == FAX_HOME) {
field = "Fax (home): ";
} else if (i == FAX_WORK) {
field = "Fax (work): ";
} else if (i == PAGER) {
field = "Pager: ";
} else if (i == EMAIL_HOME) {
field = "Email (home): ";
} else if (i == EMAIL_WORK) {
field = "Email (work): ";
} else if (i == EMAIL) {
field = "Email: ";
} else if (i == ORGANISATION) {
field = "Company: ";
} else if (i == JOB_TITLE) {
field = "Job title: ";
} else if (i == ADDRESS_HOME) {
field = "Address (home): ";
} else if (i == ADDRESS_WORK) {
field = "Address (work): ";
} else if (i == ADDRESS) {
field = "Address: ";
} else if (i == IM_SKYPE) {
field = "Skype: ";
} else if (i == IM_GOOGLE) {
field = "Google Talk: ";
} else if (i == IM_JABBER) {
field = "Jabber: ";
} else if (i == IM_YAHOO) {
field = "Yahoo: ";
} else if (i == IM_MSN) {
field = "MSN: ";
} else if (i == IM_ICQ) {
field = "ICQ: ";
} else if (i == IM_AIM) {
field = "AIM: ";
} else if (i == TWITTER) {
field = "Twitter: ";
} else if (i == BIRTHDAY) {
field = "Birthday: ";
} else if (i == ANNIVERSARY) {
field = "Anniversary: ";
} else if (i == NOTES) {
field = "Notes: ";
} else if (i == WEBSITE) {
field = "Website: ";
} else {
continue;
}
if (readableVCard.length() != 0) {
readableVCard.append("\n");
}
readableVCard.append(field);
for (int j = 0; j < vCardDataField.size(); j++) {
if (j != 0) {
readableVCard.append("; ");
}
readableVCard.append(vCardDataField.get(j));
}
}
}
if (readableVCard.length() != 0) {
String textVCard = readableVCard.toString();
try {
textVCard = qpDecoder.decode(readableVCard.toString());
} catch (Exception e) {
Logger.e("VCard to UTF-8", e.getMessage());
}
return (textVCard);
}
}
return (null);
}
So my current output is like this:
Name: Marko
Phone(mobile):1312
Phone(fax):441231
Phone(home):543534
Email(home):dddd
Email(work):eeee
Email(other):aaaa
What I want is to add a line break between groups (name/phone/email) so I get something like this:
Name: Marko
Phone(mobile):1312
Phone(fax):441231
Phone(home):543534
Email(home):dddd
Email(work):eeee
Email(other):aaaa
Addressblablabla
.
.
.
IMsblablabla
.
.
.
Can someone help please?
Thanks.
You could iterate the string array, splitting by : and then checking if next item starts with current. If it does, then do nothing, if it doesn't you add the line break to current item and replace it in the array.
Note: splitting with : also separates all phone (xxx) types. To avoid this, you can create enum type, map type to Phone if the string starts with "phone" and use that enum as current type while iterating through the array. If current type if different than next type you add line break.
You can append line separator via
System.getProperty("line.separator");