羽毛球

生活在别处

导航

<2005年11月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

统计

留言簿(29)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜

Google™ Code Jam - 中国编程挑战赛模拟题三

 Google™ Code Jam - 中国编程挑战赛 


Problem Statement

     When editing a single line of text, there are four keys that can be used to move the cursor: end, home, left-arrow and right-arrow. As you would expect, left-arrow and right-arrow move the cursor one character left or one character right, unless the cursor is at the beginning of the line or the end of the line, respectively, in which case the keystrokes do nothing (the cursor does not wrap to the previous or next line). The home key moves the cursor to the beginning of the line, and the end key moves the cursor to the end of the line.

You will be given a int, N, representing the number of character in a line of text. The cursor is always between two adjacent characters, at the beginning of the line, or at the end of the line. It starts before the first character, at position 0. The position after the last character on the line is position N. You should simulate a series of keystrokes and return the final position of the cursor. You will be given a string where characters of the string represent the keystrokes made, in order. 'L' and 'R' represent left and right, while 'H' and 'E' represent home and end.

Definition

    
Class: CursorPosition
Method: getPosition
Parameters: string, int
Returns: int
Method signature: int getPosition(string keystrokes, int N)
(be sure your method is public)
    

Constraints

- keystrokes will be contain between 1 and 50 'L', 'R', 'H', and 'E' characters, inclusive.
- N will be between 1 and 100, inclusive.

Examples

0)
    
"ERLLL"
10
Returns: 7
First, we go to the end of the line at position 10. Then, the right-arrow does nothing because we are already at the end of the line. Finally, three left-arrows brings us to position 7.
1)
    
"EHHEEHLLLLRRRRRR"
2
Returns: 2
All the right-arrows at the end ensure that we end up at the end of the line.
2)
    
"ELLLELLRRRRLRLRLLLRLLLRLLLLRLLRRRL"
10
Returns: 3
3)
    
"RRLEERLLLLRLLRLRRRLRLRLRLRLLLLL"
19
Returns: 12

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.


我的解答

#include <string>

using namespace std;

const char LEFT = 'L';
const char RIGHT = 'R';
const char HOME = 'H';
const char END = 'E';

class CursorPosition
{
public:
    
int getPosition(string keystrokes, int N);
}
;

int CursorPosition::getPosition(string keystrokes, int N)
{
    
int nCurrPos = 0;
    
    
int i=0;
    
for (i = 0; i < keystrokes.length(); i++)
    
{
        
if (LEFT == keystrokes.at(i))
        
{
            
if (nCurrPos > 0)
            
{
                nCurrPos
--;
            }

        }

        
else if (RIGHT == keystrokes.at(i))
        
{
            
if (nCurrPos < N)
            
{
                nCurrPos
++;
            }

        }

        
else if (HOME == keystrokes.at(i))
        
{
            nCurrPos 
= 0;
        }

        
else if (END == keystrokes.at(i))
        
{
            nCurrPos 
= N;
        }

    }


    
return nCurrPos;
}

posted on 2005-11-26 22:20 Michael 阅读(3513) 评论(5)  编辑 收藏

评论

# re: Google™ Code Jam - 中国编程挑战赛模拟题三 2005-11-28 13:45 周星星

我没有看你的题目,只看了你的代码,我觉得有几个小问题:
1. CursorPosition 和 getPosition 是什么关系呀?实在看不出用 CursorPosition 套住 getPosition 的用意。
2. LEFT等等和CursorPosition和getPosition四处分散我也觉得奇怪。
3. getPosition命名也许没问题,但这种Java命名方式从不在C++中使用。
4. string是个很不严格的参数类型,它可以包含任意值的元素,但从你的代码上看来,却只允许它包含'L'、'R'、'H'、'E'这四种。
5. 使用int作为位置信息类型也同样如此,既然坐标不可以为负,那么就尽量别用可以为负值的类型。
6. 如果成员函数不改变类的逻辑含义,那么应当申明为const。
7. 参数keystrokes同样如此,且可以传引用。
8. 为什么不把int i定义到内部,任由其肆意扩大作用范围和生命周期?
9. 看来你很喜欢用后++,而不是前++,我觉得这个习惯不好。
10. 既然for中限定了下标范围,何必再去用at检查一次;既然用了at,为什么不配套的使用try-catch?
11. 不从效率上去考虑,仅从代码可读性上看,这里用switch也胜过if-else好多,switch中的case是相互无关的,而if-else则不如此。比如
if ...
else if ...
else if( a == 2 ) b = 1;
当 a 等于 2 时,你能保证执行b=1?肯定不能,因为你不知道前面的条件判断对此是否有影响。

-------------------------

#include <vector>
#include <cassert>
using namespace std;

class CursorPosition
{
public:
    enum drct { LEFT = 'L', RIGHT = 'R', HOME = 'H', END = 'E' };
    typedef vector<drct> ks;
    size_t getpos( const ks& keystrokes, size_t n ) const;
};

size_t CursorPosition::getpos( const ks& keystrokes, size_t n ) const
{
    size_t nCurrPos = 0;
    for( ks::const_iterator itor=keystrokes.begin(); itor!=keystrokes.end(); ++itor )
    {
        switch( *itor )
        {
        case LEFT:
            if( 0 != nCurrPos ) --nCurrPos;
            break;
        case RIGHT:
            if( n > nCurrPos ) ++nCurrPos;
            break;
        case HOME:
            nCurrPos = 0;
            break;
        case END:
            nCurrPos = n;
        default:
            assert( false );
        }
    }
    return nCurrPos;
}

int main()
{
    return 0;
}

# re: Google™ Code Jam - 中国编程挑战赛模拟题三 2005-11-28 13:47 周星星

上面少了个break;
我几次拷贝后,不小心弄丢了。

# re: Google™ Code Jam - 中国编程挑战赛模拟题三 2005-11-28 13:51 heroboy

楼上说了那么多,只因为没看题目
看了题目的话可以少那么2,3条

# 回复周星星 2005-11-29 12:54 Michael

1 3 6 7 题目已经制定函数的声明(signature)
如果你以自己的方式写这个函数,自动测试程序无法测试你的类,你的分数也将是0

2 不太明白

4 同意. 检查一下包含非允许字符

5 int类型没什么不恰当的

8 不符合ISO标准,其他编译器不允许通过。

9 个人习惯,不是坏习惯

10 同意. 用下标访问效率会高一些

11 同意用switch case

# to 周星星 //re: Google™ Code Jam - 中国编程挑战赛模拟题三 2005-11-29 23:33 乾坤一笑

9. 看来你很喜欢用后++,而不是前++,我觉得这个习惯不好。
----------
来,星星给讲讲,为什么后++不好?我发现很多老外的大师都喜欢用前++,我一直不明白差别在那里?
比如:
for(int i=0; i<100; ++i)

for(int i=0; i<100; i++)

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]