查看: 6981| 回复: 8
跳转到指定楼层
上一主题 下一主题
收起左侧

[FACEBOOK] Reverse Polish Notation

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
定义一种叫做“Reverse Polish Notation”的表达式:

3 + (4 * 5)

可以写成

3 4 5 * +

即运算符号写在数字的后面。

现在规定,x代表数字,*代表运算符。给定一个包含有x和*的string,问最少需要多少次操作(操作包括,添加一个字符,删除一个字符,替代一个字符)可以使一个string符合Reverse Polish Notation的表达方式。

Input:
第一行: 数字n,代表有n组数据
第2~n+1行:一个包含有x和*的string

Output:
输出一个数字,代表最少需要多少次操作,string可以符合Reverse Polish Notation的表达方式

Sample Input:
5
x
xx*
xxx**
*xx
xx*xx**

Sample Output:
0
0
0
2
0

上一篇:有人愿意继续组织下面的open course学习吗?
下一篇:use divide and conquer to solve Longest Increasing Subsequence problem
🔗
secretgu 2012-4-14 15:37:33 | 只看该作者
全局:
本帖最后由 secretgu 于 2012-4-17 12:34 编辑

废了老大劲= =开始对 **** 这样的输入考虑有误。。。


没有像题目要求的input那样,只让用户输入一个字符串,不过这本来也不是这题的本质,所以感觉没太大关系
时间复杂度O(N)空间复杂度O(1)

求review code,设计test case,有发现代码问题或test case不通过请跟帖指出,谢谢~


  1. #include <iostream>

  2. using namespace std;

  3. int *s, count;
  4. string str;

  5. void swap(int i, int j) {
  6.         int tmp = s[i];
  7.         s[i] = s[j];
  8.         s[j] = tmp;
  9. }

  10. int main() {
  11.         // init
  12.         cout << "input an expression: ";
  13.         cin >> str;
  14.         s = new int[str.size()];
  15.         int i, countx = 0;
  16.         for (i = 0; i < str.size(); ++i)
  17.                 s[i] = i;

  18.         int j = str.size() - 1; // points to last 'x'
  19.         while (j >= 0 && str[j] == '*')
  20.                 j--;
  21.         for (i = 0; i < str.size(); ++i) {
  22.                 if (str[i] == '*') {
  23.                         if (i - 1 >= 0 && s[i - 1] - 1 >= 0) {
  24.                                 // there are two x' waited to be reduced
  25.                                 s[i] = s[s[i - 1] - 1];
  26.                         } else {
  27.                                 if (i < j) {
  28.                                         swap(i, j--);
  29.                                         count += 2; // swap char makes count += 2
  30.                                         while (j >= 0 && str[j] == '*')
  31.                                                 j--;
  32.                                 } else
  33.                                         break;
  34.                         }
  35.                 } else
  36.                         countx++;
  37.         }

  38.         int bk_x = countx, bk_s = str.size() - countx;
  39.         if (bk_x > bk_s) {
  40.                 while (bk_x - bk_s > 1) {
  41.                         // replace one x with one *
  42.                         bk_x--;
  43.                         bk_s++;
  44.                         count++;
  45.                 }
  46.         } else {
  47.                 while (bk_s - bk_x > 0) {
  48.                         // replace one * with one x
  49.                         bk_s--;
  50.                         bk_x++;
  51.                         count++;
  52.                 }
  53.                 if (bk_s == bk_x)
  54.                         count++; // delete one *
  55.         }

  56.         cout << "count: " << count << endl;

  57.         return 0;
  58. }
复制代码
回复

使用道具 举报

🔗
eastflag 2012-4-17 12:22:42 | 只看该作者
全局:
本帖最后由 eastflag 于 2012-4-17 19:10 编辑

动态规划递归实现。每个xx*运算产生x,设计数器num,指针从字符串开头开始查找,如果找到第一个*,作如下处理:
1、若该*前面有2个(或以上)x,删去这两个x和*,首端增加一个x,递归余下字符串;
2、若该*前面只有1个x,num++
     1)对应操作:加一个x或删去*,,递归除去*余下部分;
    2)对应操作:替换*为x,递归替换后余下部分;
3、若该*前面没有x,num++
      1)对应操作:删去*,递归余下部分;
    2)对应操作:替换*为x,递归替换后余下部分;

如果没有找到而字符串长度>1,num++,加上一个*,递归余下字符串。

代码如下(java)(如何对齐啊。。。):



  1. public class RPN{
  2. public static void main(String[] args){
  3.   String[] testCases = {
  4.     new String("x"),
  5.     new String("xx"),
  6.     new String("***"),
  7.     new String("xxx"),
  8.     new String("xxx***"),
  9.     new String("***xxx"),
  10.     new String("x*xx*"),
  11.     new String("*xx*x"),
  12.   };
  13.   
  14.   for (String testCase : testCases){
  15.    //TODO check input legal
  16.    System.out.println(new RPN().operate(testCase));
  17.   }
  18. }

  19. private int operate(String tc){
  20.   if (tc.equals("x")) {
  21.    return 0;
  22.   }else if (tc.equals("") || tc.equals("*")){
  23.    return 1;
  24.   }
  25.   
  26.   int pos = tc.indexOf('*');
  27.   
  28.   if (pos < 0) {
  29.    return min (operate(tc.substring(1)),
  30.      operate(tc.substring(2))) + 1;
  31.   }else if (pos == 0){
  32.    return min(operate(tc.substring(pos + 1)),  //delete *
  33.      operate('x' + tc.substring(pos + 1)) //replace * with x
  34.      ) + 1;
  35.   }else if (pos == 1){
  36.    return min(operate('x' + tc.substring(pos + 1)), //add x or delete *
  37.      operate("xx" + tc.substring(pos + 1)) //replace * with x
  38.      ) + 1;
  39.   }else{
  40.    return operate(tc.substring(0, pos - 1) + tc.substring(pos + 1));
  41.   }
  42. }

  43. private static int min(int ...a){
  44.   int m = a[0];
  45.   for (int k : a){
  46.    if (k < m) {
  47.     m = k;
  48.    }
  49.   }
  50.   return m;
  51. }
  52. }
复制代码
回复

使用道具 举报

🔗
eastflag 2012-4-17 15:42:32 | 只看该作者
全局:
回复 2# secretgu


    你的代码里面count没有定义,是不是和countx是一个变量?
回复

使用道具 举报

🔗
secretgu 2012-4-17 15:44:28 | 只看该作者
全局:
回复 4# eastflag

第5行,全局变量
回复

使用道具 举报

🔗
eastflag 2012-4-17 15:58:27 | 只看该作者
全局:
回复 5# secretgu


    哦,你count需要设一下初值0,另外不知道为什么我的dev C++里面你的全局的count不能用,提示没有定义。。。

关于testCase,你测试一下,样例*x 输出应该是1,你输出3,类似的*xxx你输出了3,这些好像都有问题。
回复

使用道具 举报

🔗
secretgu 2012-4-17 16:04:35 | 只看该作者
全局:
回复 6# eastflag

我用gcc编译运行的,全局变量自动赋值为0,是可以用的

恩,我回头看看,总算有人帮看code了- -。。。谢了- -
回复

使用道具 举报

🔗
zlxwd 2012-4-17 17:41:54 | 只看该作者
全局:
本帖最后由 zlxwd 于 2012-4-17 17:47 编辑

动态规划,时间复杂度为O(N^2),空间复杂度为O(N^2)

  1. import java.util.*;
  2. import java.math.*;
  3. public class Main {
  4.    
  5.     private static void set(int[][] dp, int i, int j, int val) {
  6.         if (dp[i][j] == -1) {
  7.             dp[i][j] = val;
  8.         }
  9.         else {
  10.             dp[i][j] = Math.min(dp[i][j], val);
  11.         }
  12.     }
  13.    
  14.     public static void main(String[] args) throws Exception {
  15.         Scanner scan = new Scanner(System.in);
  16.         int taskCount = scan.nextInt();
  17.         scan.nextLine();
  18.         for (int taskIndex = 0; taskIndex < taskCount; taskIndex++) {
  19.             char[] arr = scan.nextLine().toCharArray();
  20.             if (arr.length == 0) {
  21.                 System.out.println("Input string cannot be empty");
  22.                 continue;
  23.             }
  24.             else if (arr.length == 1) {
  25.                 System.out.println(arr[0] == '*' ? 1 : 0);
  26.                 continue;
  27.             }
  28.             int[][] dp = new int[arr.length][arr.length];
  29.             for (int i = 0; i < dp.length; i++) {
  30.                 Arrays.fill(dp[i], -1);
  31.             }
  32.             if (arr[0] == 'x') {
  33.                 dp[0][0] = 0;
  34.             }
  35.             else {
  36.                 dp[0][0] = 1;
  37.             }
  38.             for (int i = 1; i < arr.length; i++) {
  39.                 if (arr[i] == 'x') {
  40.                     set(dp, i, 1, dp[i - 1][0]);
  41.                     set(dp, i, 0, dp[i - 1][0] + 1);
  42.                 }
  43.                 else {
  44.                     set(dp, i, 1, dp[i - 1][0] + 1);
  45.                     set(dp, i, 0, dp[i - 1][0] + 1);
  46.                 }
  47.                 for (int j = 1; j < arr.length; j++) {
  48.                     if (dp[i - 1][j] == -1) {
  49.                         continue;
  50.                     }
  51.                     if (arr[i] == 'x') {
  52.                         set(dp, i, j + 1, dp[i - 1][j]);
  53.                         set(dp, i, j, dp[i - 1][j] + 1);
  54.                         set(dp, i, j - 1, dp[i - 1][j] + 1);
  55.                     }
  56.                     else {
  57.                         set(dp, i, j + 1, dp[i - 1][j] + 1);
  58.                         set(dp, i, j, dp[i - 1][j] + 1);
  59.                         set(dp, i, j - 1, dp[i - 1][j]);
  60.                     }
  61.                 }
  62.             }
  63.             
  64.             int result = arr.length;
  65.             for (int i = 0; i < arr.length; i++) {
  66.                 if (dp[dp.length - 1][i] == -1) {
  67.                     continue;
  68.                 }
  69.                 result = Math.min(result, dp[dp.length - 1][i] + i);
  70.             }
  71.             System.out.println(result);
  72.         }
  73.     }
  74. }

复制代码
回复

使用道具 举报

🔗
gboystal 2012-7-28 10:55:29 | 只看该作者
全局:
zlxwd 发表于 2012-4-17 17:41
动态规划,时间复杂度为O(N^2),空间复杂度为O(N^2)

请教一下你代码里面的dp[i][j]表示的是什么意义?
另外,感觉@eastflag的做法有点像递归搜索呢。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表