将句子的单词顺序逆序

package partice1;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Stack;

/**
 * “student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”
 */
public class ReverseSetence
{
    /**
     * 先将每一个单词逆序, 然后再将句子整体逆序
     * 时间复杂度O(N) , 空间复杂度O(1) , 但由于java string是不可变字符串, 所以由此带来的空间复杂度为O(N), 用c则没有这个...
     */
    public String ReverseSentence_best(String str)
    {
        if(str == null || str.length() == 0 )
            return str ;

        char[] chars = str.toCharArray() ;
        int left = 0 ;
        int right = 0 ;

        boolean change = false ;  //用于表示数组是否发生过逆序, 用于防止只有一个单词的句子出现, 如整个句子只有student一个单词, 就不需要整体逆序, 直接输出即可
        while (right < str.length())
        {
            boolean flag = false ; //用于标记不是空格的字母是否是第一个, 如果是就赋值给left进行逆序;  这个可以防止中间有多个空格如: student  i am这种情况
            while (right < chars.length && chars[right] != ‘ ‘)
            {
                if(!flag)
                {
                    left = right ;
                    flag = true ;
                }
                right++ ;
            }

            if(flag)
            {
                change = true ;
                int r = right - 1;
                while (left < r)
                {
                    swap(chars, left++, r--);
                }
            }
            right++ ;
        }

        if(change)
        {
            left = 0;
            right = chars.length-1;
            while (left < right)
                swap(chars, left++, right--);
        }
        return new String(chars) ;
    }

    private void swap(char[] chars , int p , int q)
    {
        chars[p] ^= chars[q] ;
        chars[q] ^= chars[p] ;
        chars[p] ^= chars[q] ;
    }
  
   /**
     * 这个是我第一次写的时候的思路, 使用一个辅助栈来进行逆序输出, 不好, 时间复杂度O(N), 空间复杂度O(N)
     */
    public String ReverseSentence(String str)
    {
        if(str == null || str.length() == 0)
            return str ;
        Stack<String> stack = new Stack<>() ;

        int from = -1 ;
        for(int i=0 ; i<str.length() ; i++)
        {
            if(str.charAt(i) == ‘ ‘)
            {
                if(from != -1)
                {
                    stack.push(str.substring(from , i)) ;
                    from = -1 ;
                }
                stack.push(" ") ;
            }
            else if(from == -1)
            {
                from = i ;
            }
        }

        if(from != -1)
            stack.push(str.substring(from)) ;

        StringBuilder sb = new StringBuilder(str.length()) ;

        while (!stack.isEmpty())
        {
            sb.append(stack.pop()) ;
        }

        return sb.toString() ;
    }

    public static void main(String[] args)
    {
        ArrayList<String> list = new ArrayList<>() ;
        list.add("i‘m a studnet") ;
        list.add("hello") ;
        list.add("  i am  a student   ") ;

        Iterator<String> it = list.iterator() ;

        while (it.hasNext())
        {
            String str = it.next() ;
            System.out.println("|" + new ReverseSetence().ReverseSentence_best(str)+"|");
        }
    }
}
时间: 2024-12-16 11:43:18

将句子的单词顺序逆序的相关文章

软件工程导论课后习题Github作业(把一个英文句子中的单词次序逆序,单词中字母正常排列)

Java源代码  package yly; import java.util.Scanner; public class ruanjian { public static void main(String[] args) { // TODO Auto-generated method stub String q = "how are you"; String[] aa=(String[]) q.split(" "); for(int i = aa.length ;i

按单词逆序句子(含标点)

主要思想:先写出单词逆序的函数,再写整个句子逆序的函数(在其中查找单词,找到后调用单词逆序的函数逆序,最后将整个句子逆序). 程序缺点:只能识别几个常用的标点符号 源代码及测试程序: //给定一个字符串,按单词将该字符串逆序,含标点 #include<stdio.h> //start 和 end 之间逆序的函数 void reverse_word(char *start, char *end) { while(start < end) { *start = *start ^ *end;

字符串逆序小结

1.普通逆序         可以任意申请内存或变量,对于指针版本,此方法不好,需要在函数内开辟空间,在函数结束前返回该空间首地址,由于不能释放该内存,出现内存泄漏 ,所以这里只提供引用版本: #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> using namespace std; void Reverse(string &str) { int len = str.size(); i

字符串逆序

普通逆序 基本上没有这么考的,放在这里主要是为了和后面的原地逆序做个对比.很简单,直接分配一个与原字符串等长的字符数组,然后反向拷贝一下即可. char* Reverse(char* s) {    //将q指向字符串最后一个字符     char* q = s ;    while( *q++ ) ;     q -= 2 ;      //分配空间,存储逆序后的字符串.     char* p = newchar[sizeof(char) * (q - s + 2)] ;      char

按单词将句子逆序

给定一个字符串,按单词将该字符串逆序,比如给定"This is a boy",则输出是"boy a is This",为了简化问题,字符串中不包含标点符号. 分两步 1 先按单词逆序得到"sihT si a yob" 2 再整个句子逆序得到"boy a is This" //头文件 #include <stdio.h> #include <stdlib.h> #include <string.h&

英文句子中的单词逆序

#include "stdafx.h" #include <iostream> #include <string> #include <stack> using namespace std; int main(int arc, char** argv) { string str="I come from liaoning."; stack<string> works; int len=str.length(); whi

[面试算法题重做]翻转句子中单词的顺序

话说工作中算法用的真的多么?????? 虽然工作中用不到,但是你总得换工作吧,防不住笔试面试中问你些这么个玩意. 而且,多思考,有助于活跃头脑了.深深扎入项目中童鞋们还可以活跃活跃,防止生锈. 话不多说,题目如下: 题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.句子中单词以空格符隔开.为简单起见,标点符号和普通字母一样处理. 例如输入“I am a student.”,则输出“student. a am I”. 在何海涛的日记中,分析方法是 先颠倒句子中的所有字符.这时,

21:句子逆序

21:题目描述 将一个英文语句以单词为单位逆序排放.例如“I am a boy”,逆序排放后为“boy a am I” 所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符 public String reverse(String sentence); 输入描述:将一个英文语句以单词为单位逆序排放. 输出描述:得到逆序的句子 输入例子:I am a boy 输出例子:boy a am I package prctice01; import java.util.Scanner; /*

第10题:翻转句子中单词的顺序

欢迎转载,转载请务必注明出处:http://blog.csdn.net/alading2009/article/details/44906243 第10题:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.句子中单词以空格符隔开.为简单起见,标点符号和普通字母一样处理.例如输入"I am a student.",则输出"student. a am I". 此题就是对序列求逆,正如矩阵求逆 (AB)?1=B?1A?1,AB可以是子字符串,再单独对其进行求