Java 罗马到整数-但使用“a”;不同的;罗马数制
我参加了一次面试,面试中我表现得很糟糕。所以,现在我正试图找到问题的答案。以下是采访问题: “我们有以下映射:Java 罗马到整数-但使用“a”;不同的;罗马数制,java,string,algorithm,roman-numerals,Java,String,Algorithm,Roman Numerals,我参加了一次面试,面试中我表现得很糟糕。所以,现在我正试图找到问题的答案。以下是采访问题: “我们有以下映射: M:1000,D:500,C:100,L:50,X:10,V:5,I:1 我们有以下规则: 每个字母映射到一个正整数值 将这些值相加,除了 …当一个值(或相同值的运行数)后跟一个更大的值时,将减去该运行数的总和 示例: IIX->8 麦克米克斯->1808 我们得到了这个Java方法:int-valueOfRoman(char-roman)。 我们已经实现了Java方法:introma
M:1000,D:500,C:100,L:50,X:10,V:5,I:1 我们有以下规则:
int-valueOfRoman(char-roman)
。
我们已经实现了Java方法:intromantoint(strings)
”
我知道这不是一个合适的罗马数字系统,但这才是真正的问题
我能够为一个合适的罗马体系编写一个有效的解决方案。但我无法改变它,使之适应这些新规则,特别是规则3。我试过了,但没有成功。我现在的解决方案是,对于IIX,它打印10,而不是正确答案8。这是我的代码(我还为我的测试实现了
valueOf
):
static int-romanToInt(字符串s){
半货币;
国际货币;
char-prev;
int-prevVal;
int total=阿曼的价值(s.charAt(0));
对于(int i=1;i当前值){
总计=总计-(2*prevVal);
}
}
返回总数;
}
Roman的静态int值(字符c){
如果(c='M'){
返回1000;
}else如果(c='D'){
返回500;
}else如果(c=='c'){
返回100;
}else如果(c=='L'){
返回50;
}else如果(c='X'){
返回10;
}else如果(c='V'){
返回5;
}else如果(c=='I'){
返回1;
}
返回-1;
}
非常感谢您的帮助。如果你能告诉我如何修改我的代码,那将特别有用。谢谢
编辑:我对方法的名称进行了编辑,使它们更清晰。以下是我解决问题的方法:
- 逐个字符读取字符串,并在每个步骤中记下当前字符和上一个字符。
- 如果当前字符与前一字符相同,则将游程长度增加1
- 如果当前字符的值小于前一个字符的值,则将前一个字符的游程长度*值添加到总计,然后将游程长度重置为1
- 如果当前字符的值大于上一个字符的值,则从总数中减去游程长度*上一个字符的值,然后将游程长度重置为1
- 这种问题通常很容易用递归的思维方式解决。解决方案可能如下所示:
public int rom2int(String s)
{
if(s.length() == 0)
// no string --> 0
return 0;
else if(s.length() == 1)
// One Character --> Value of Character
return valueOf(s.charAt(0));
else if((valueOf(s.charAt(0)) > valueOf(s.charAt(1))) )
// The value is NOT followed by a greater value --> We had the value
return rom2int(s.substring(1, s.length())) + valueOf(s.charAt(0));
else if(valueOf(s.charAt(0)) <= valueOf(s.charAt(1)) )
// The value is followed by a greater (or same) value --> We substract the value
return rom2int(s.substring(1, s.length())) - valueOf(s.charAt(0));
else
// Shouldn't Happen. 0 as neutral element in in a Sum.
return 0;
}
public int-rom2int(字符串s)
{
如果(s.length()==0)
//无字符串-->0
返回0;
如果(s.length()==1),则为else
//一个字符-->字符的值
返回值为(s.charAt(0));
如果((s.charAt(0))的值>s.charAt(1))的值)
//该值后面没有更大的值-->我们得到了该值
返回rom2int(s.substring(1,s.length())+valueOf(s.charAt(0));
否则,如果(s.charAt(0))的值减去该值
返回rom2int(s.substring(1,s.length())-valueOf(s.charAt(0));
其他的
//不应该发生。0作为求和中的中性元素。
返回0;
}
即使递归解决方案被禁止,在我看来,取消递归这个算法要比在第一次尝试时找到过程性的算法简单得多
编辑:
我的结果:
MCCMIIX的值为:1808
IIX值为:8
IVX值为:4
IIVVL的值为:38
我对它的看法
编辑更改#2
public class Romans {
private int valueOf(char c) {
if (c == 'M') {
return 1000;
} else if (c == 'D') {
return 500;
} else if (c == 'C') {
return 100;
} else if (c == 'L') {
return 50;
} else if (c == 'X') {
return 10;
} else if (c == 'V') {
return 5;
} else if (c == 'I') {
return 1;
}
return 0;
}
public int rom2int(String s) {
int currVal;
int runValue = 0;
int repetition = 0;
int total = 0;
boolean alreadyAdded = false;
for (int i = 0; i < s.length(); i++) {
currVal = valueOf(s.charAt(i));
if (runValue == 0) {
runValue = currVal;
repetition = 1;
alreadyAdded = false;
} else if (currVal > runValue) {
total = total + (currVal - (runValue * repetition));
repetition = 1;
runValue = currVal;
alreadyAdded = true;
} else if (currVal < runValue) {
if(!alreadyAdded) {
total += (runValue * repetition);
}
repetition = 1;
runValue = currVal;
alreadyAdded = false;
} else {
repetition++;
alreadyAdded = false;
}
}
if (!alreadyAdded) {
total += (runValue * repetition);
}
return total;
}
}
产出:
Value of MVVV is: 1015
Value of IIX is: 8
Value of MCCMIIX is: 1808
Value of IVX is: 9
我的take-works与您提供的公认的小测试一起工作
static int rom2int(String s) {
if (s == null || s.length() == 0) {
return 0;
}
// Total value.
int total = 0;
// The most recent.
char current = s.charAt(0);
// Total for the current run.
int run = valueOf(current);
for (int i = 1; i < s.length(); i++) {
char next = s.charAt(i);
int value = valueOf(next);
if (next == current) {
// We're in a run - just keep track of its value.
run += value;
} else {
// Up or down?
if (value < valueOf(current)) {
// Gone down! Add.
total += run;
} else {
// Gone UP! Subtract.
total -= run;
}
// Run ended.
run = valueOf(next);
}
// Kee track of most recent.
current = next;
}
return total + run;
}
private void test(String s) {
System.out.println("Value of " + s + " = " + rom2int(s));
}
public void test() {
test("IVX");
test("IIVVL");
test("IIX");
test("MCCMIIX");
test("MVVV");
}
我就是这样做的
它适用于您提到的两个值(IIX=8和MCCMIIX=1808):
所以IVX的答案是14所以,没有人明白我的暗示。那我也试试看。我不会进入“IVX”-因为我认为这是语法错误。
int romanToInt( String s ){
int total = 0;
int pivot = 0;
for( int i = s.length()-1; i >= 0; i--){ // We start at the **end**
int current = valueOfRoman((s.charAt(i));
if( current >= pivot ){ // We will have at least "I", so it **will** be > pivot for 1st char.
pivot = current;
total += pivot;
}else{
total -= current;
}
}
return total;
}
让我们看看:IIX
i char value total pivot -> total pivot
2 X 10 0 0 > 10 10
1 I 1 10 10 < 9 10
0 I 1 9 10 < 8 10
i char值总轴->总轴
2 X 10 0 0>10 10
1i11010<910
01910<810
麦克米克斯
i char value total pivot -> total pivot
6 X 10 0 0 > 10 10
5 I 1 10 10 < 9 10
4 I 1 9 10 < 8 10
3 M 1000 8 10 > 1008 1000
2 C 100 1008 1000 < 908 1000
1 C 100 908 1000 < 808 1000
0 M 1000 808 1000 = 1808 1000
i char值总轴->总轴
6 X 10 0 0>10 10
5I11010<910
4 I 19 10<8 10
3米1000 8 10>1008 1000
2 C 100 1008 1000<908 1000
1 C 100 908 1000<808 1000
0米1000 808 1000=1808 1000
为了简洁起见,该方法省略了输入验证。我假设所有输入都已检查,并且根据“规则”只包含允许的字符。这似乎是一个有效的解决方案,有什么问题吗?是否有一个输入会产生不需要的输出?我现在的解决方案是,对于IIX,它打印10,而不是正确的答案8。你似乎假设每次运行都有2个长度,这是不能保证的。您应该跟踪当前相同数字的运行时间。“IVX”应生成什么值?提示:从右侧开始。如何威胁“IVX”?像(10-5)-1还是像1+(10-5)?@J
public static int rom2int(String s)
{
int currVal = 0, prevVal = 0, subTotal = 0, total = 0;
for (int i = 0; i < s.length(); i++) {
currVal = valueOf(s.charAt(i));
if (currVal > 0) {
if (prevVal == 0) {
subTotal = currVal;
}
else if (currVal > prevVal) {
total += (currVal - subTotal);
subTotal = 0;
}
else if (currVal < prevVal) {
total += subTotal;
subTotal = currVal;
}
else if (currVal == prevVal) {
subTotal += currVal;
}
prevVal = currVal;
}
}
total += subTotal;
return total;
}
public static int valueOf(char c)
{
if (c == 'M')
return 1000;
if (c == 'D')
return 500;
if (c == 'C')
return 100;
if (c == 'L')
return 50;
if (c == 'X')
return 10;
if (c == 'V')
return 5;
if (c == 'I')
return 1;
return 0;
}
IVX = 1 5 10
if 5 > 1 then 5 - 1 = 4
if 10 > 5 then 10 - 0(*) = 10 (*) we already have used V(5) before, so we discard it.
int romanToInt( String s ){
int total = 0;
int pivot = 0;
for( int i = s.length()-1; i >= 0; i--){ // We start at the **end**
int current = valueOfRoman((s.charAt(i));
if( current >= pivot ){ // We will have at least "I", so it **will** be > pivot for 1st char.
pivot = current;
total += pivot;
}else{
total -= current;
}
}
return total;
}
i char value total pivot -> total pivot
2 X 10 0 0 > 10 10
1 I 1 10 10 < 9 10
0 I 1 9 10 < 8 10
i char value total pivot -> total pivot
6 X 10 0 0 > 10 10
5 I 1 10 10 < 9 10
4 I 1 9 10 < 8 10
3 M 1000 8 10 > 1008 1000
2 C 100 1008 1000 < 908 1000
1 C 100 908 1000 < 808 1000
0 M 1000 808 1000 = 1808 1000