zoukankan      html  css  js  c++  java
  • XNA游戏开发之字符篇

    摘要:

    游戏中开发不同于一般应用程序的开发,它更注重于界面美观,我们需要在游戏界面设计中花费大量的时间以便使它看起来更炫、更酷,当然这其中就少不了游戏中的字符文本,那么如何制作出漂亮的游戏文本呢?今天我们就一起来看一下。

    内容:

    在XNA中2D文本的绘制方式种类比较多,这有助于我们制作出更美观的文本效果,下面我就逐一来看一下。

    一、SpriteFont

    这种方式在XNA游戏开发中应该算是最基本的一种形式,使用方法就是在游戏对应的Content项目中添加SpriteFont文件(右键Add—New Item—Sprite Font)。之后你会看到生成了一个XML格式的文件:

    View Code
    <?xml version="1.0" encoding="utf-8"?>
    <XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
    <Asset Type="Graphics:FontDescription">
    <FontName>Segoe UI Mono</FontName><!--字体类型-->
    <Size>30</Size><!--字体大小-->
    <Spacing>0</Spacing><!--字符间距-->
    <UseKerning>true</UseKerning><!--字体布局-->
    <Style>Regular</Style><!--字体风格,如加粗、倾斜等-->
    <CharacterRegions><!--字体区间,例如只显示ASCII字体-->
    <CharacterRegion>
    <Start></Start>
    <End>~</End>
    </CharacterRegion>
    </CharacterRegions>
    </Asset>
    </XnaContent>

    在这个文件中定义了你使用的字体类型、字体大小、字符间距等信息。值得一提的是上面的字体区间,它的意思是指你在游戏中使用的的字符范围,从上面的值可以看出是ASCII的32-126,具体对应字符如下:

    ASCII码

    字符

    ASCII码

    字符

    ASCII码

    字符

    ASCII码

    字符

    ASCII码

    字符

    ASCII码

    字符

    ASCII码

    字符

    ASCII码

    字符

    32

    [空格]

    33

    !

    34

    "

    35

    #

    36

    $

    37

    %

    38

    &

    39

    '

    40

    (

    41

    )

    42

    *

    43

    +

    44

    ,

    45

    -

    46

    .

    47

    /

    48

    0

    49

    1

    50

    2

    51

    3

    52

    4

    53

    5

    54

    6

    55

    7

    56

    8

    57

    9

    58

    :

    59

    ;

    60

    <

    61

    =

    62

    >

    63

    ?

    64

    @

    65

    A

    66

    B

    67

    C

    68

    D

    69

    E

    70

    F

    71

    G

    72

    H

    73

    I

    74

    J

    75

    K

    76

    L

    77

    M

    78

    N

    79

    O

    80

    P

    81

    Q

    82

    R

    83

    S

    84

    T

    85

    U

    86

    V

    87

    W

    88

    X

    89

    Y

    90

    Z

    91

    [

    92

    \

    93

    ]

    94

    ^

    95

    _

    96

    `

    97

    a

    98

    b

    99

    c

    100

    d

    101

    e

    102

    f

    103

    g

    104

    h

    105

    i

    106

    j

    107

    k

    108

    l

    109

    m

    110

    n

    111

    o

    112

    p

    113

    q

    114

    r

    115

    s

    116

    t

    117

    u

    118

    v

    119

    w

    120

    x

    121

    y

    122

    z

    123

    {

    124

    |

    125

    }

    126

    ~

       

    当然它几乎涵盖了所有常用英文字符。之所以要定义这个区间主要是为了减少游戏资源,毕竟在一个游戏中并不是所有的字符我们都要用到。到这里可能会有朋友问,既然如此我要是使用中文怎么办,这个区间肯定不够啊,中文有两万多个字符,定义这个区间的意义也不大啊?

    事实上我们如果需要用到中文字符的话一般并不是修改这个区间(当然修改它是可以做到的,但是占用资源十分大,毕竟字符太过了),而是通过Font Description Processor来处理。具体做法就是:准备一个txt文件,其中存放我们游戏中要用到的中文字符,例如我们建立一个FontDescription.txt文件,里面写上"中文字体"四个字存放到游戏的Content项目中;接着在解决方案中添加一个Content Pipeline Extension Library(4.0)类型的项目,然后编写一个类继承于FontDescriptionProcesor,重写Process方法。在这个方法中我们读取外部的一个txt文件,当然你也可以直接写到代码中或存储到其他位置,然后将txt文件中的字符(当然我们这里是中文字符了)读取到FontDescription中,具体代码如下:

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Content.Pipeline;
    using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
    using Microsoft.Xna.Framework.Content.Pipeline.Processors;
    using System.IO;
    using System.Text;
    using System.ComponentModel;
    namespace ContentPipelineExtensionDemo
    {
    [ContentProcessor(DisplayName
    ="ContentPipelineExtensionDemo.MyContentProcessor")]//这个名字将用于SpriteFont的Content Processor属性
    publicclass MyContentProcessor : FontDescriptionProcessor
    {
    privatestring fDescription =@"../XNAGameFontContent/Fonts/FontDescription.txt";//注意这里的路径,因为FontDescription.txt文件在XNAGameFontContent项目的Fonts文件夹中
    publicoverride SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
    {
    string path = Path.GetFullPath(fDescription);
    context.AddDependency(path);
    string content = File.ReadAllText(path,Encoding.UTF8);//FontDescription.txt文件必须保存成utf-8格式,此处也需使用utf-8读取
    foreach (char c in content)//读取文件中字符,存放到FontDescription中
    {
    input.Characters.Add(c);
    }
    returnbase.Process(input, context);
    }
    }
    }

    做完上面两步之后,此时文件目录结构如图:

    文档结构图

    这里需要注意两点:FontDescription.txt文件必须保存成utf-8;由于文件在Content项目中默认XNAGameFontContent中的文件都需要进行编译,编译时会自动检测里面的文件类型,而txt文件不属于这其中任何类型,因此我们需要修改它的BuildAction属性为None。接下来我们在XNAGameFontContent下面中添加对ContentPipelineExtensionDemo生成的dll文件的引用,然后在XNAGameFontContent项目上右键选择Project Dependencies,弹出如下图窗口:

    项目依赖窗口

    在Project项中选择XNAGameFont,Depends on中勾选ContentPipelineExtensionDemo,确定,以此添加游戏项目对内容管道扩展的依赖(这样一来就可以修改SpriteFont文件的Processor为我们自定义的扩展内容)。最后我们在XNAGameFontContent项目中添加SpriteFontForChinese.spritefont文件(上面txt中只是定义了中文字符的范围,在这里可以指定字体类型、字体大小等信息),文件内容如下:

    View Code
    <?xml version="1.0" encoding="utf-8"?>
    <XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
    <Asset Type="Graphics:FontDescription">
    <FontName>华文行楷</FontName>
    <Size>30</Size>
    <Spacing>0</Spacing>
    <UseKerning>true</UseKerning>
    <Style>Regular</Style>
    <CharacterRegions>
    <CharacterRegion>
    <Start></Start>
    <End>~</End>
    </CharacterRegion>
    </CharacterRegions>
    </Asset>
    </XnaContent>

    修改文件的Content Processor属性为我们自定义的ContentPipelineExtensionDemo.MyContentProcessor(这就是上面添加依赖关系的原因),然后我们就可以在游戏中使用我们文本中的中文汉字了。具体使用时的代码如下:

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Input.Touch;
    using Microsoft.Xna.Framework.Media;
    namespace XNAGameFont
    {
    publicclass MyGame : Microsoft.Xna.Framework.Game
    {
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    SpriteFont sf1;
    //SpriteFont文本
    Vector2 sfPosition;//SpritFont文本所在位置
    SpriteFont sfChinese;//SpriteFont中文文本
    Vector2 sfChinesePosition;//SpriteFont中文文本的显示位置
    public MyGame()
    {
    graphics
    =new GraphicsDeviceManager(this);
    Content.RootDirectory
    ="Content";
    graphics.PreferredBackBufferWidth
    =480;
    graphics.PreferredBackBufferHeight
    =800;
    TargetElapsedTime
    = TimeSpan.FromTicks(333333);
    }
    protectedoverridevoid Initialize()
    {
    sfPosition
    =new Vector2(130,200);
    sfChinesePosition
    =new Vector2(160, 400);
    base.Initialize();
    }
    protectedoverridevoid LoadContent()
    {
    spriteBatch
    =new SpriteBatch(GraphicsDevice);
    sf1
    = Content.Load<SpriteFont>(@"Fonts/SpriteFont");
    sfChinese
    = Content.Load<SpriteFont>(@"Fonts/SpriteFontForChinese");
    }
    protectedoverridevoid UnloadContent()
    {
    }
    protectedoverridevoid Update(GameTime gameTime)
    {
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
    this.Exit();
    base.Update(gameTime);
    }
    protectedoverridevoid Draw(GameTime gameTime)
    {
    GraphicsDevice.Clear(Color.CornflowerBlue);
    spriteBatch.Begin();
    spriteBatch.DrawString(sf1,
    "SpriteFont", sfPosition, Color.White);
    spriteBatch.DrawString(sfChinese,
    "中文字体", sfChinesePosition, Color.Red);
    spriteBatch.End();
    base.Draw(gameTime);
    }
    }
    }

    运行效果如图:

    基本SpriteFont和中文字符扩展后的运行效果

    二、SpriteFontTexture

    由于SpriteFont文本对于显示效果的调整很有限,因此XNA又对其进行了扩充。SpriteFontTexture事实上是以图片来作为XNA的字符集,我们实现只要制作好相关字符的图片,然后像使用SpriteFont一样使用就可以了。当然使用起来很简单,主要问题就是如何来制作图片字库了。这个不用担心,很多牛人早已经想过这类问题了,下面我们看几种这类工具:

    2.1 ttf2bmp

    ttf2bmp是一个制作字符库的简单工具,并且它是开源的,有了它我们就可以轻松制作图片字符库了。工具如下图:

    ttf2bmp工具截图

    我们将需要的字符编码范围确定下来,在Min char中输入最小字符编码,在Max char中输入最大字符编码,然后点击Export就可以生成类似于下面的图片:

    ttf2bmp生成的字符集图片

    将上图添加到XNAGameFontContent下面的Fonts文件夹中,接下来就可以写代码使用了,当然这时我们的字符图片在XNAGameFontContent下面中默认的是Textrue图片类型,还需要修改图片的Processor属性为Sprite Font Texture - XNA Framework。具体使用代码如下:

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Input.Touch;
    using Microsoft.Xna.Framework.Media;
    namespace XNAGameFont
    {
    publicclass MyGame : Microsoft.Xna.Framework.Game
    {
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    SpriteFont sfTexture;
    //Sprite Font Texture文本(ttf2bmp制作)
    Vector2 sfTexturePosition;//Sprite Font Texture文本位置
    public MyGame()
    {
    graphics
    =new GraphicsDeviceManager(this);
    Content.RootDirectory
    ="Content";
    graphics.PreferredBackBufferWidth
    =480;
    graphics.PreferredBackBufferHeight
    =800;
    TargetElapsedTime
    = TimeSpan.FromTicks(333333);
    }
    protectedoverridevoid Initialize()
    {
    sfTexturePosition
    =new Vector2(60, 350);
    base.Initialize();
    }
    protectedoverridevoid LoadContent()
    {
    spriteBatch
    =new SpriteBatch(GraphicsDevice);
    sfTexture
    = Content.Load<SpriteFont>(@"Fonts/SpriteFontTexture");
    }
    protectedoverridevoid UnloadContent()
    {
    }
    protectedoverridevoid Update(GameTime gameTime)
    {
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
    this.Exit();
    base.Update(gameTime);
    }
    protectedoverridevoid Draw(GameTime gameTime)
    {
    GraphicsDevice.Clear(Color.CornflowerBlue);
    spriteBatch.Begin();
    spriteBatch.DrawString(sfTexture,
    "Sprite Font Texture", sfTexturePosition, Color.Yellow);
    spriteBatch.End();
    base.Draw(gameTime);
    }
    }
    }

    运行效果如图:

    2.2 SpriteFont2

    准确的来说SpriteFont2应该是对ttf2bmp的扩展,默认的ttf2bmp生成的字体效果比较单一(当然也可以利用一些图形处理工具(如:Photoshop)来对生成的图片进行处理),SpriteFont2则可以制作出更炫的效果,例如字体填充色、边框、投影、发光等。下面是工具的截图:

    SpriteFont2工具截图

    使用这个工具我们制作下面一张Sprite Font Texture图片:

    SpriteFont2生成的字符集图片

    然后添加到XNAGameFontContent项目的Fonts文件夹,当然别忘了修改片的Processor属性为Sprite Font Texture - XNA Framework。然后再就可以在程序中使用我们制作的字体:

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Input.Touch;
    using Microsoft.Xna.Framework.Media;
    namespace XNAGameFont
    {
    publicclass MyGame : Microsoft.Xna.Framework.Game
    {
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    SpriteFont sfTextureExtend;
    //Sprite Font Texture文本效果扩展(spritefont2制作)
    Vector2 sfTextureExtendPosition;//Sprite Font Texture Extend文本位置
    public MyGame()
    {
    graphics
    =new GraphicsDeviceManager(this);
    Content.RootDirectory
    ="Content";
    graphics.PreferredBackBufferWidth
    =480;
    graphics.PreferredBackBufferHeight
    =800;
    TargetElapsedTime
    = TimeSpan.FromTicks(333333);
    }
    protectedoverridevoid Initialize()
    {
    sfTextureExtendPosition
    =new Vector2(100, 330);
    base.Initialize();
    }
    protectedoverridevoid LoadContent()
    {
    spriteBatch
    =new SpriteBatch(GraphicsDevice);
    sfTextureExtend
    = Content.Load<SpriteFont>(@"Fonts/SpriteFontTexture2");
    }
    protectedoverridevoid UnloadContent()
    {
    }
    protectedoverridevoid Update(GameTime gameTime)
    {
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
    this.Exit();
    base.Update(gameTime);
    }
    protectedoverridevoid Draw(GameTime gameTime)
    {
    GraphicsDevice.Clear(Color.CornflowerBlue);
    spriteBatch.Begin();
    spriteBatch.DrawString(sfTextureExtend,
    "SFT 2", sfTextureExtendPosition, Color.White);
    spriteBatch.End();
    base.Draw(gameTime);
    }
    }
    }

     

    运行效果:

    SpriteFont2制作的字符集运行效果图

    2.3 XNA Bitmap Font Plus

    XNA Bitmap Font Plus不是一个直接按照字符编码范围生成相关字体图片的工具,它的字体来源于图片或者剪贴板,这里我们主要说如何从剪贴板加载字体,首先我们在PowerPoint中按顺序编辑好我们常用的字符,就是ASCII从32-126之间的字符:

    View Code
    !"#$%&'()*+,-./
    0123456789:;<=>?
    @ABCDEFGHIJKLMNO
    PQRSTUVWXYZ[\]
    ^_
    `abcdefghIjklmno
    pqrstuvwxyz{
    |}~

    然后调整字符的样式,修改字符间距:

    调整过的字符在powerpoint中截图

    接着 ctrl+c复制,此时字符信息复制到了剪贴板,打开XNA Bitmap Font Plus,它会自动加载剪贴板的内容,如下图:

    粘贴过之后打开XNA Bitmap Font Plus后的截图

    当然此时我们需要调整字符行数、偏移量和间隔等信息,点击Generate Bitmap Font按钮查看效果是否符合我们的要求:

    调整后的XNA Bitmap Font Plus截图

    当调整好之后,我们就可以点击Save Image As…按钮来保存生成的图片:

    XNA Bitmap Font Plus生成的字符集图片

    最后将图片添加到XNAGameFontContent项目的Fonts文件夹,修改图片的Processor属性为Sprite Font Texture - XNA Framework。就可以在程序中使用我们制作的字体:

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Input.Touch;
    using Microsoft.Xna.Framework.Media;
    namespace XNAGameFont
    {
    publicclass MyGame : Microsoft.Xna.Framework.Game
    {
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    SpriteFont sfTexturePlus;
    //Sprite Font Texture文本(xna bitmap font plus制作)
    Vector2 sfTexturePlusPosition;//Sprite Font Texture 文本位置
    public MyGame()
    {
    graphics
    =new GraphicsDeviceManager(this);
    Content.RootDirectory
    ="Content";
    graphics.PreferredBackBufferWidth
    =480;
    graphics.PreferredBackBufferHeight
    =800;
    TargetElapsedTime
    = TimeSpan.FromTicks(333333);
    }
    protectedoverridevoid Initialize()
    {
    sfTexturePlusPosition
    =new Vector2(40, 350);
    base.Initialize();
    }
    protectedoverridevoid LoadContent()
    {
    spriteBatch
    =new SpriteBatch(GraphicsDevice);
    sfTexturePlus
    = Content.Load<SpriteFont>(@"Fonts/SpriteFontTexture3");
    }
    protectedoverridevoid UnloadContent()
    {
    }
    protectedoverridevoid Update(GameTime gameTime)
    {
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
    this.Exit();
    base.Update(gameTime);
    }
    protectedoverridevoid Draw(GameTime gameTime)
    {
    GraphicsDevice.Clear(Color.CornflowerBlue);
    spriteBatch.Begin();
    spriteBatch.DrawString(sfTexturePlus,
    "Sprite Font Texture 3", sfTexturePlusPosition, Color.White);
    spriteBatch.End();
    base.Draw(gameTime);
    }
    }
    }

    运行效果:

    下面给出所有以上这几种字体综合到一起的代码:

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Input.Touch;
    using Microsoft.Xna.Framework.Media;
    namespace XNAGameFont
    {
    publicclass MyGame : Microsoft.Xna.Framework.Game
    {
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    SpriteFont sf1;
    //SpriteFont文本
    Vector2 sfPosition;//SpritFont文本所在位置
    SpriteFont sfChinese;//SpriteFont中文文本
    Vector2 sfChinesePosition;//SpriteFont中文文本的显示位置
    SpriteFont sfTexture;//Sprite Font Texture文本(ttf2bmp制作)
    Vector2 sfTexturePosition;//Sprite Font Texture文本位置
    SpriteFont sfTextureExtend;//Sprite Font Texture文本效果扩展(spritefont2制作)
    Vector2 sfTextureExtendPosition;//Sprite Font Texture Extend文本位置
    SpriteFont sfTexturePlus;//Sprite Font Texture文本(xna bitmap font plus制作)
    Vector2 sfTexturePlusPosition;//Sprite Font Texture 文本位置
    public MyGame()
    {
    graphics
    =new GraphicsDeviceManager(this);
    Content.RootDirectory
    ="Content";
    graphics.PreferredBackBufferWidth
    =480;
    graphics.PreferredBackBufferHeight
    =800;
    TargetElapsedTime
    = TimeSpan.FromTicks(333333);
    }
    protectedoverridevoid Initialize()
    {
    sfPosition
    = Vector2.Zero;
    sfChinesePosition
    =new Vector2(0, 100);
    sfTexturePosition
    =new Vector2(0, 200);
    sfTextureExtendPosition
    =new Vector2(0, 300);
    sfTexturePlusPosition
    =new Vector2(0, 400);
    base.Initialize();
    }
    protectedoverridevoid LoadContent()
    {
    spriteBatch
    =new SpriteBatch(GraphicsDevice);
    sf1
    = Content.Load<SpriteFont>(@"Fonts/SpriteFont");
    sfChinese
    = Content.Load<SpriteFont>(@"Fonts/SpriteFontForChinese");
    sfTexture
    = Content.Load<SpriteFont>(@"Fonts/SpriteFontTexture");
    sfTextureExtend
    = Content.Load<SpriteFont>(@"Fonts/SpriteFontTexture2");
    sfTexturePlus
    = Content.Load<SpriteFont>(@"Fonts/SpriteFontTexture3");
    }
    protectedoverridevoid UnloadContent()
    {
    }
    protectedoverridevoid Update(GameTime gameTime)
    {
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
    this.Exit();
    base.Update(gameTime);
    }
    protectedoverridevoid Draw(GameTime gameTime)
    {
    GraphicsDevice.Clear(Color.CornflowerBlue);
    spriteBatch.Begin();
    spriteBatch.DrawString(sf1,
    "SpriteFont", sfPosition, Color.White);
    spriteBatch.DrawString(sfChinese,
    "中文字体", sfChinesePosition, Color.Red);
    spriteBatch.DrawString(sfTexture,
    "Sprite Font Texture", sfTexturePosition, Color.Yellow);
    spriteBatch.DrawString(sfTextureExtend,
    "SFT 2", sfTextureExtendPosition, Color.White);
    spriteBatch.DrawString(sfTexturePlus,
    "Sprite Font Texture 3", sfTexturePlusPosition, Color.White);
    spriteBatch.End();
    base.Draw(gameTime);
    }
    }
    }

    最终效果:

    最终综合效果图

    OK,就到这里吧!

    最后附上源代码(上面提到的几个工具,都可以点击相关链接下载):

    download

    知识共享许可协议 作品采用知识共享署名 2.5 中国大陆许可协议进行许可,欢迎转载,演绎或用于商业目的。但转载请注明来自崔江涛(KenshinCui),并包含相关链接。
  • 相关阅读:
    oracle 之索引,同义词 ,关键词,视图 ,存储过程,函数,触发器
    基于TCP协议的socket通信
    支付宝支付 -即时到帐
    Hibernate延迟加载机制
    shiro 简单的身份验证 案例
    linux 试题
    程序员面试题精选100题(16)-O(logn)求Fibonacci数列[算法]
    九度OJ 1362 左旋转字符串(Move!Move!!Move!!!)【算法】
    九度OJ 1366 栈的压入、弹出序列 【数据结构】
    九度OJ 1387 斐波那契数列
  • 原文地址:https://www.cnblogs.com/kenshincui/p/2011695.html
Copyright © 2011-2022 走看看