剑指Offer面试题:34.翻转单词顺序VS左旋转字符串
一、题目一:翻转单词顺序
1.1 题目说明
题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student.",则输出"student. a am I"。
1.2 解题思路
第一步翻转句子中所有的字符。比如翻转"I am a student."中所有的字符得到".tneduts a ma I",此时不但翻转了句子中单词的顺序,连单词内的字符顺序也被翻转了。
这个步骤我们大多数都很熟悉,看看下面这个Reverse方法,是不是非常熟悉?
public static void Reverse(char[] array, int start, int end)
{
if (array == null || start < 0 || end > array.Length - 1)
{
return;
}
while (start < end)
{
char temp = array[start];
array[start] = array[end];
array[end] = temp;
start++;
end--;
}
}
第二步再翻转每个单词中字符的顺序,就得到了"student.a am I"。这正是符合题目要求的输出。因此,我们可以将上述思路实现为以下代码:
public static string ReverseSentense(string sentense)
{
if (string.IsNullOrEmpty(sentense))
{
return null;
}
char[] array = sentense.ToCharArray();
int start = 0;
int end = array.Length - 1;
// Step1.先翻转整个句子
Reverse(array, start, end);
// Step2.再翻转句中的每个单词
start = end = 0;
while (start < array.Length)
{
if (array[start] == ' ')
{
start++;
end++;
}
else if (end == array.Length || array[end] == ' ')
{
Reverse(array, start, --end);
start = end + 1;
end++;
}
else
{
end++;
}
}
return new string(array);
}
1.3 单元测试
(1)测试用例
// 功能测试,句子中有多个单词
[TestMethod]
public void ReverseTest1()
{
string input = "I am a student.";
string actual = ReverseWordsHelper.ReverseSentense(input);
string expected = "student. a am I";
Assert.AreEqual(actual, expected);
}
// 功能测试,句子中只有一个单词
[TestMethod]
public void ReverseTest2()
{
string input = "Wonderful";
string actual = ReverseWordsHelper.ReverseSentense(input);
string expected = "Wonderful";
Assert.AreEqual(actual, expected);
}
// 边界值测试,测试空字符串
[TestMethod]
public void ReverseTest3()
{
string input = "";
string actual = ReverseWordsHelper.ReverseSentense(input);
Assert.AreEqual(actual, null);
}
// 边界值测试,字符串中只有空格
[TestMethod]
public void ReverseTest4()
{
string input = " ";
string actual = ReverseWordsHelper.ReverseSentense(input);
string expected = " ";
Assert.AreEqual(actual, expected);
}
// 鲁棒性测试
[TestMethod]
public void ReverseTest5()
{
string actual = ReverseWordsHelper.ReverseSentense(null);
Assert.AreEqual(actual, null);
}
(2)测试结果
①测试用例通过情况
②代码覆盖率统计
二、题目二:左旋转字符串
2.1 题目说明
题目二:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如输入字符串"abcdefg"和数字2,该函数将返回左旋转2位得到的结果"cdefgab"。
2.2 解题思路
这两个问题是非常相似的,我们同样可以通过翻转字符串的办法来解决第二个问题。
以"abcdefg"为例,我们可以把它分为两部分。由于想把它的前两个字符移到后面,我们就把前两个字符分到第一部分,把后面的所有字符都分到第二部分。我们先分别翻转这两部分,于是就得到"bagfedc"。接下来我们再翻转整个字符串,得到的"cdefgab"刚好就是把原始字符串左旋转2位的结果。
通过分析可以发现,我们只需要调用三次Reverse方法就可以实现字符串的左旋转功能。
public static string LeftRotateString(string str, int num)
{
if (string.IsNullOrEmpty(str))
{
return null;
}
int strLength = str.Length;
char[] array = str.ToCharArray();
if (strLength > 0 && num > 0 && num < strLength)
{
int firstStart = 0;
int firstEnd = num - 1;
int secondStart = num;
int secondEnd = strLength - 1;
// 翻转字符串的前面n个字符
Reverse(array, firstStart, firstEnd);
// 翻转字符串的后面部分
Reverse(array, secondStart, secondEnd);
// 翻转整个字符串
Reverse(array, 0, strLength - 1);
}
return new string(array);
}
2.3 单元测试
(1)测试用例
// 功能测试
[TestCategory("LeftRotate")]
[TestMethod]
public void RotateTest1()
{
string input = "abcdefg";
string actual = ReverseWordsHelper.LeftRotateString(input, 2);
string expected = "cdefgab";
Assert.AreEqual(actual, expected);
}
// 边界值测试
[TestCategory("LeftRotate")]
[TestMethod]
public void RotateTest2()
{
string input = "abcdefg";
string actual = ReverseWordsHelper.LeftRotateString(input, 1);
string expected = "bcdefga";
Assert.AreEqual(actual, expected);
}
// 边界值测试
[TestCategory("LeftRotate")]
[TestMethod]
public void RotateTest3()
{
string input = "abcdefg";
string actual = ReverseWordsHelper.LeftRotateString(input, 6);
string expected = "gabcdef";
Assert.AreEqual(actual, expected);
}
// 鲁棒性测试
[TestCategory("LeftRotate")]
[TestMethod]
public void RotateTest4()
{
string actual = ReverseWordsHelper.LeftRotateString(null, 6);
Assert.AreEqual(actual, null);
}
// 鲁棒性测试
[TestCategory("LeftRotate")]
[TestMethod]
public void RotateTest5()
{
string input = "abcdefg";
string actual = ReverseWordsHelper.LeftRotateString(input, 0);
string expected = "abcdefg";
Assert.AreEqual(actual, expected);
}
// 鲁棒性测试
[TestCategory("LeftRotate")]
[TestMethod]
public void RotateTest6()
{
string input = "abcdefg";
string actual = ReverseWordsHelper.LeftRotateString(input, 7);
string expected = "abcdefg";
Assert.AreEqual(actual, expected);
}
(2)测试结果
①用例通过情况
②代码覆盖率
作者:周旭龙
出处:http://edisonchou.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
- Linux下的计算命令和求和、求平均值、求最值命令梳理
- 网卡自适应带来的麻烦
- silverlight:手写板/涂鸦/墨迹/InkPresenter示例程序
- Linux下日志文件监控系统Logwatch的使用记录
- .net中使用oracle数据库分页的土办法
- 图表的一些资源
- 删除文件后,磁盘空间没有释放的处理记录
- silverlight:ListBox中如何取得DateTemplate/ItemsPanelTemplate中的命名控件?
- 表格效果2
- Linux终端复用神器-Tmux使用梳理
- 程序实现下载文件或者打开文件
- VisualTreeHelper
- Linux下路由配置梳理
- Gitlab利用Webhook实现Push代码后的jenkins自动构建
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法