How to change UnicodeCategory in java? - java

I'm trying to migrate this C# code to Java.
Is there any possibility to migrate the unicodeCategory to a regex in Java, or is there a possibility to do the Unicode category by Java directly?
foreach (var currentChar in preNormalizedString)
{
var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(currentChar);
//https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(System.Globalization.UnicodeCategory.LowercaseLetter);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.6);k(DevLang-csharp)&rd=true
switch (unicodeCategory)
{
//case UnicodeCategory.NonSpacingMark:
//case UnicodeCategory.SpacingCombiningMark:
//case UnicodeCategory.EnclosingMark:
case UnicodeCategory.DashPunctuation:
case UnicodeCategory.ConnectorPunctuation:
case UnicodeCategory.OpenPunctuation:
case UnicodeCategory.ClosePunctuation:
case UnicodeCategory.OtherPunctuation:
case UnicodeCategory.LineSeparator:
case UnicodeCategory.MathSymbol:
case UnicodeCategory.ModifierSymbol:
case UnicodeCategory.OtherSymbol:
case UnicodeCategory.SpaceSeparator:
case UnicodeCategory.ParagraphSeparator:
if (!isPreviousSpaceChar)
builder.Append(" ");
isPreviousSpaceChar = true;
break;
case UnicodeCategory.Control:
case UnicodeCategory.CurrencySymbol:
case UnicodeCategory.EnclosingMark:
case UnicodeCategory.NonSpacingMark:
case UnicodeCategory.SpacingCombiningMark:
case UnicodeCategory.InitialQuotePunctuation:
case UnicodeCategory.FinalQuotePunctuation:
case UnicodeCategory.Format:
case UnicodeCategory.ModifierLetter:
case UnicodeCategory.OtherNotAssigned:
case UnicodeCategory.PrivateUse:
case UnicodeCategory.Surrogate:
// Caratères ignorés.
break;
case UnicodeCategory.LowercaseLetter:
case UnicodeCategory.UppercaseLetter:
case UnicodeCategory.LetterNumber:
case UnicodeCategory.DecimalDigitNumber:
case UnicodeCategory.OtherLetter:
case UnicodeCategory.OtherNumber:
case UnicodeCategory.TitlecaseLetter:
default:
builder.Append(currentChar);
isPreviousSpaceChar = false;
break;
}
}
var normalizedString = builder.ToString() ?? string.Empty;
normalizedString = normalizedString.ToUpper();
normalizedString = normalizedString.Trim();
return normalizedString;

There is a getType(char) that will return an int that you can then compare with a list of constants that are enumerated in the Java Docs.
Note that both C# code and the getType(char) are "wrong" because they don't support non-BMP characters (characters that use two char). But splitting a string in its "Rune" was a little more complex in C# until .NET Core 3.0.
public static String convert(String preNormalizedString) {
StringBuilder builder = new StringBuilder();
boolean isPreviousSpaceChar = false;
for (int i = 0; i < preNormalizedString.length(); i++) {
char currentChar = preNormalizedString.charAt(i);
int unicodeCategory = Character.getType(currentChar);
switch (unicodeCategory) {
case Character.DASH_PUNCTUATION:
case Character.CONNECTOR_PUNCTUATION:
//... You'll have to complete the list
if (!isPreviousSpaceChar)
builder.append(" ");
isPreviousSpaceChar = true;
break;
case Character.CONTROL:
case Character.CURRENCY_SYMBOL:
//... You'll have to complete the list
// Caratères ignorés.
break;
case Character.LOWERCASE_LETTER:
case Character.UPPERCASE_LETTER:
//... You'll have to complete the list
default:
builder.append(currentChar);
break;
}
}
String normalizedString = builder.toString();
normalizedString = normalizedString.toUpperCase();
normalizedString = normalizedString.trim();
return normalizedString;
}

Related

How do I execute this Java Code that goes infinite loops?

public class Exercise3_10 {
public static void main(String[] args) {
int array[][] = new int[4][4]; // array는 4x4의 2차원 배열
int i;
boolean duplicate_index[] = new boolean[16];
for(i=0;i<16;i++) // duplicate_index 배열의 모든 원소에 false를 삽입
{
duplicate_index[i] = false;
}
for(i=0; i<10; i++)
{
int random_index = (int)Math.random()*15; // 0부터 15까지의 인덱스를 랜덤으로 뽑기
if(!duplicate_index[random_index]) // duplicate_index배열의 랜덤 인덱스의 원소가
{ // false라면 array배열에 랜덤숫자 부여 후 true로 변경
int random_number = (int)(Math.random()*10+1); // 1부터 10까지 랜덤 정수 뽑기
switch(random_index)
{
case 0: case 1: case 2: case 3:
array[0][random_index] = random_number;
duplicate_index[random_index] = true;
break;
case 4: case 5: case 6: case 7:
array[1][random_index - 4] = random_number;
duplicate_index[random_index] = true;
break;
case 8: case 9: case 10: case 11:
array[1][random_index - 8] = random_number;
duplicate_index[random_index] = true;
break;
case 12: case 13: case 14: case 15:
array[1][random_index - 12] = random_number;
duplicate_index[random_index] = true;
break;
}
}
else // true인 경우 현재 반복문을 한번 더 실행
{
i--;
continue;
}
}
for(i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
System.out.print(array[i][j] + " ");
}
System.out.println();
}
}
}
i want to make a two-dimentional array.
then, i need ten random numbers (range 1~10) in random index.
the rest of indexes are '0'.
i made a following code. but, this code didnt show any output in eclipse.
i think it goes infinite loop. but i dont know whats wrong.
i need your helps!!

Making singular words plural trouble

I am making a program which can make singular words plural, however I am unsure how I would go about checking the exceptions in the string array I created. I know there are more exceptions, but for now I just want to get what I have working. I made a method called "checkExceptions", but what would I put inside of it for the program to check that method first before moving on?
import java.util.Scanner;
public class FormingPlurals {
static final String SENTINEL = "done";
static final Scanner IN = new Scanner(System.in);
static String[] exceptions = {"fish", "fox", "deer", "moose", "sheep", "cattle"};
public static void run() {
while (true) {
System.out.println("Enter a word to make it plural. Enter 'done' to stop: ");
String noun = IN.nextLine();
if (noun.toLowerCase().equals(SENTINEL)) {
System.out.println("Goodbye...");
break;
}
System.out.println(makePlural(noun) + " ");
}
}
public static void checkExceptions() {
}
static String makePlural(String singularWord) {
String pluralWord = "";
int length = singularWord.length();
String checker = singularWord.substring(0, singularWord.length() - 1);
char lastLetter = singularWord.charAt(singularWord.length() - 1);
if (length == 1) {
pluralWord = singularWord + "'s";
} else
switch (lastLetter) {
case 's':
case 'x':
case 'z':
pluralWord = singularWord + "es";
break;
case 'h':
if ((singularWord.charAt(singularWord.length() - 2) == 'c') || (singularWord.charAt(singularWord.length() - 2) == 's')) {
pluralWord = singularWord + "es";
break;
}
case 'f':
if (EnglishConsonant(singularWord.charAt(singularWord.length() - 2))) {
pluralWord = checker + "ves";
break;
}
case 'y':
if (EnglishConsonant(singularWord.charAt(singularWord.length() - 2))) {
pluralWord = checker + "ies";
break;
}
default:
pluralWord = singularWord + "s";
break;
}
return pluralWord;
}
public static boolean EnglishConsonant(char ch) {
switch (Character.toLowerCase(ch)) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return false;
default:
return true;
}
}
public static void main(String[] args) {
run();
}
}
It is also possible to do that with arrays, but it is easier to use a map in this case. You could create a map
Map<String,String> irregularPlurals = new HashMap<>();
irregularPlurals.put("sheep","sheep");
irregularPlurals.put("fox","foxes");
Then you could use simply Map interface's methods like get() or containsKey() to check if a given word is has an irregular plural form. A simple method to check it would then be:
String irregularPlural = irregularPlurals.get(singularWord);
if (irregularPlural != null){
return irregularPlural ;
}
BTW, it would be a good idea to rename the methods checkException(), as in Java exceptions and checked exceptions are language concepts, so a reader may think that that method is about handling Java exceptions.
For one, I'd place the exceptions array inside makePlural itself and handle it there.
Secondly, I'd go from the most specialized case to the least one, so
First look at word exceptions
Look at special plurals like 'es', 'ves' etc.
add 's' to the word and return it
Also, the moment I find a match in either the exceptions or special plurals, I'd calculate and immediately return the result, to prevent other rules from matching and adding more stuff to pluralWord
If I had to use a function for the exceptions, it would be
public static boolean isException(String word){
String[] exceptions={"fish", "deer"};
for(int i=0;i<exceptions.length();i++) {
if(exceptions[i].equals(word))
return true;
}
return false;
}

Switch case for a group of inputs?

Given that I have the following finals:
private static final char CLIPPING_LOWER = 'c';
private static final char CLIPPING_UPPER = 'C';
private static final char RESET_LOWER = 'r';
private static final char RESET_UPPER = 'R';
private static final char LOAD_LOWER = 'l';
private static final char LOAD_UPPER = 'L';
private static final char QUIT_LOWER = 'q';
private static final char QUIT_UPPER = 'Q';
And consider the switch-case:
public void keyPressed(KeyEvent e)
{
char usersChoice = e.getKeyChar(); // get the user's choice
switch(usersChoice)
{
case LOAD_UPPER:
{
userPressedLoad();
break;
}
case LOAD_LOWER:
{
userPressedLoad();
break;
}
case RESET_LOWER:
{
userPressedReset();
break;
}
case RESET_UPPER:
{
userPressedReset();
break;
}
case CLIPPING_LOWER:
{
userPressedClipping();
break;
}
case CLIPPING_UPPER:
{
userPressedClipping();
break;
}
case QUIT_UPPER:
{
userPressedQuit();
break;
}
case QUIT_LOWER:
{
userPressedQuit();
break;
}
default:
break;
}
}
Is it possible to write a case for both c and C in one block (and also r and R ... etc) instead of writing a separate case for c and another case for C?
One solution to group the cases together
case LOAD_UPPER:
case LOAD_LOWER:
userPressedLoad();
break;
Another solution is to convert the input to uppercase and use only uppercase in switch statement
char usersChoice = Character.toUpperCase(e.getKeyChar());
case LOAD_UPPER:
userPressedLoad();
break;
You can user Character.toLowerCase with usersChoice, that way you don't have to handle 'R', 'C', etc.
http://docs.oracle.com/javase/6/docs/api/java/lang/Character.html#toLowerCase(char)
case CLIPPING_LOWER:
case CLIPPING_UPPER: {
userPressedClipping();
break;
}
Yes like this for instance:
case LOAD_UPPER: case LOAD_LOWER:
{
userPressedLoad();
break;
}

java string.contains in switch statement

How can I convert the following code to switch statement?
String x = "user input";
if (x.contains("A")) {
//condition A;
} else if (x.contains("B")) {
//condition B;
} else if(x.contains("C")) {
//condition C;
} else {
//condition D;
}
There is a way, but not using contains. You need a regex.
final Matcher m = Pattern.compile("[ABCD]").matcher("aoeuaAaoe");
if (m.find())
switch (m.group().charAt(0)) {
case 'A': break;
case 'B': break;
}
You can't switch on conditions like x.contains(). Java 7 supports switch on Strings but not like you want it. Use if etc.
Condition matching is not allowed in java in switch statements.
What you can do here is create an enum of your string literals, and using that enum create a helper function which returns the matched enum literal. Using that value of enum returned, you can easily apply switch case.
For example:
public enum Tags{
A("a"),
B("b"),
C("c"),
D("d");
private String tag;
private Tags(String tag)
{
this.tag=tag;
}
public String getTag(){
return this.tag;
}
public static Tags ifContains(String line){
for(Tags enumValue:values()){
if(line.contains(enumValue)){
return enumValue;
}
}
return null;
}
}
And inside your java matching class,do something like:
Tags matchedValue=Tags.ifContains("A");
if(matchedValue!=null){
switch(matchedValue){
case A:
break;
etc...
}
#Test
public void test_try() {
String x = "userInputA"; // -- test for condition A
String[] keys = {"A", "B", "C", "D"};
String[] values = {"conditionA", "conditionB", "conditionC", "conditionD"};
String match = "default";
for (int i = 0; i < keys.length; i++) {
if (x.contains(keys[i])) {
match = values[i];
break;
}
}
switch (match) {
case "conditionA":
System.out.println("some code for A");
break;
case "conditionB":
System.out.println("some code for B");
break;
case "conditionC":
System.out.println("some code for C");
break;
case "conditionD":
System.out.println("some code for D");
break;
default:
System.out.println("some code for default");
}
}
Output:
some code for A
No you cannot use the switch with conditions
The JAVA 7 allows String to be used with switch case
Why can't I switch on a String?
But conditions cannot be used with switch
you can only compare the whole word in switch.
For your scenario it is better to use if
also HashMap:
String SomeString = "gtgtdddgtgtg";
Map<String, Integer> items = new HashMap<>();
items.put("aaa", 0);
items.put("bbb", 1);
items.put("ccc", 2);
items.put("ddd", 2);
for (Map.Entry<String, Integer> item : items.entrySet()) {
if (SomeString.contains(item.getKey())) {
switch (item.getValue()) {
case 0:
System.out.println("do aaa");
break;
case 1:
System.out.println("do bbb");
break;
case 2:
System.out.println("do ccc&ddd");
break;
}
break;
}
}

Object not updating when performing the switch statement in java

Not sure what I'm doing wrong here. But I want to change the card to the correct format.
For example given the card 1c change it to AC.
Here's some code I've been playing with:
public static void main(String[] args) {
String[] cards = {"1c", "13s"};
for (String card : cards) {
switch (card.toUpperCase()) {
case "1C":
card = card.toUpperCase().replace("1C", "AC");
break;
case "13S":
card = card.toUpperCase().replace("13S", "KS");
break;
default:
System.out.println(Arrays.toString(cards));
}
}
System.out.println(Arrays.toString(cards));
}
Any help would be great cheers.
Within the loop, card is just a local variable, and reassigning it doesn't modify the array cards. An immediate fix would be to index over the array so you can reference each element directly:
for (int i = 0; i < cards.length; i++) {
switch (cards[i].toUpperCase()) {
case "1C":
cards[i] = cards[i].toUpperCase().replace("1C", "AC");
break;
case "13S":
cards[i] = cards[i].toUpperCase().replace("13S", "KS");
break;
default:
System.out.println(Arrays.toString(cards));
}
}
Edit: to answer edhedges' comment, one would need to keep a counter variable outside the loop in order to keep using the enhanced-for syntax:
int i = 0;
for (String card : cards) {
switch (card.toUpperCase()) {
case "1C":
cards[i] = card.toUpperCase().replace("1C", "AC");
break;
case "13S":
cards[i] = card.toUpperCase().replace("13S", "KS");
break;
default:
System.out.println(Arrays.toString(cards));
}
i++;
}
Are you using Java 7? If you are not, you can't use Strings in cases.
See this problem and here(scroll down to Using Strings in switch Statements)
You can do this by the following code
public static void main(String[] args) {
String[] cards = {"1c", "13s"};
for (int i = 0 ; i < cards.length ; i++) {
switch (card[i].toUpperCase()) {
case "1C":
cards[i] = cards[i].toUpperCase().replace("1C", "AC");
break;
case "13S":
cards[i] = cards[i].toUpperCase().replace("13S", "KS");
break;
default:
System.out.println(Arrays.toString(cards));
}
}
System.out.println(Arrays.toString(cards));
}
In addition to #Paul Borella's answer I would say that this is only possible with Java 7. As Switch statement does not allow String as an expression. So you should get compilation error at line
switch(card.toUpperCase())
If you want to acheive the same functionality then you can go for Enum.
public enum Cards {
1C, 13S;
public String replacedString(){
case 1C : return "AC";
break;
case 13S : return "KS";
break;
default : return "";
}
}

Categories

Resources