打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
数据结构与算法:13 字符串与整数集合

13 字符串与整数集合

知识点:

图1 知识结构

1. 字符串

我们古人没有电影电视,没有游戏网络,所以文人们就会想出一些文字游戏来娱乐。比如宋代的李禺写了这样一首诗:“枯眼望遥山隔水,往来曾见几心知?壶空怕酌一杯酒,笔下难成和韵诗。途路阻人离别久,讯音无雁寄回迟。孤灯守夜长寥寂,夫忆妻兮父忆儿。”显然这是老公想念老婆和儿子的诗句。曾经和妻儿在一起,享受天伦之乐,现在一个人长久没有回家,也不见书信返回,望着油灯想念亲人,能不伤感吗?

可仔细一读发现,这首诗竟然可以倒过来读:“儿忆父兮妻忆夫,寂寥长夜守灯孤。迟回寄雁无音讯,久别离人阻路途。诗韵和成难下笔,酒杯一酌怕空壶。知心几见曾来往,水隔山遥望眼枯。”这表达了妻子对丈夫的思念。老公离开好久,路途遥远,难以相见。写信不知道写什么,独自喝酒也没什么兴致。只能和儿子夜夜守在家里一盏孤灯下,苦等老公的归来。

这种诗叫做回文诗。它是一种可以倒读或反复回旋阅读的诗体。刚才这首就是正读是丈夫思念妻子,倒读是妻子思念丈夫的古诗。是不是感觉很奇妙呢?在英文单词中,同样有神奇的地方。“即使是 lover 也有个 over,即使是 friend 也有个 end,即使是 believe 也有个 lie。”你会发现,本来不相干,甚至对立的两个词,却有某种神奇的联系。这可能是创造这几个单词的智者们也没有想到的问题。

今天我们就要来谈谈这些单词或句子组成字符串的相关问题。

1.1 串的定义与操作

(1)串的相关定义

  • 串(string):由零个或多个字符组成的有限序列,又名字符串,记为S=“c1c2...cn”
  • 串的长度:串中包含字符的个数。
  • 空串(null string):长度为零的串。直接用双引号""表示,在C#中也可用string.Empty来表示。

还有一些概念需要解释:

  • 空白串:由一个或多个空格组成的串。
  • 子串与主串:串中任意连续字符组成的子序列,称为该串的子串。相应的包含子串的串称为主串,即子串是主串的一部分。
  • 子串在主串中的位置:子串在主串中第一次出现时,子串第一个字符在主串中的序号。

例如:

A = “this is a string”;
B = “is”;
// B在A中的位置为2。
  • 串相等:长度相等且对应位字符相同。

(2)串的操作

串的逻辑结构和线性表很相似,不同之处在于串针对的是字符集,也就是串中的元素都是字符。因此,对于串的基本操作与线性表是有很大差别的。

  • 线性表关注的是单个元素的操作,比如查找一个元素,插入或删除一个元素。
  • 串关注的是它子串的应用问题,如查找子串位置,得到指定位置的子串、替换子串等操作。

关于串的基本操作如下:

  • 获取串的长度
  • 获取或设置指定索引处的字符
  • 在指定位置插入子串
  • 在指定位置移除给定长度的子串
  • 在指定位置取子串
  • 当前串的拷贝
  • 串连接
  • 串的匹配
  • 填充字符串
  • 去除两边空格

比如 C# 中,字符串操作还有ToLower()转小写、ToUpper()转大写等比较方便的操作,它们其实就是前面这些基本操作的扩展函数。

图2 串接口
namespace LinearStruct
{
/// <summary>
/// 串的抽象数据类型
/// </summary>
public interface IString
{
/// <summary>
/// 获取串的长度
/// </summary>
int Length { get; }

/// <summary>
/// 获取或设置指定索引处的字符
/// </summary>
/// <param name="index">要获取或设置的字符从零开始的索引</param>
/// <returns>指定索引处的字符</returns>
char this[int index] { get; set; }

/// <summary>
/// 在指定位置插入子串
/// </summary>
/// <param name="startIndex">插入的位置</param>
/// <param name="s">插入的子串</param>
/// <returns>插入串后得到的新串</returns>
IString Insert(int startIndex, IString s);

/// <summary>
/// 在指定位置移除子串
/// </summary>
/// <param name="startIndex">移除的位置</param>
/// <param name="count">移除的长度</param>
/// <returns>移除后得到的新串</returns>
IString Remove(int startIndex, int count);

/// <summary>
/// 在指定位置取子串
/// </summary>
/// <param name="startIndex">取子串的位置</param>
/// <param name="count">子串的长度</param>
/// <returns>取得的子串</returns>
IString SubString(int startIndex, int count);

/// <summary>
/// 当前串的拷贝
/// </summary>
/// <returns>当前串的拷贝</returns>
IString Clone();

/// <summary>
/// 串连接
/// </summary>
/// <param name="s">在尾部要连接的串</param>
/// <returns>连接后得到的新串</returns>
IString Concat(IString s);

/// <summary>
/// 串的匹配
/// </summary>
/// <param name="value">要匹配的子串</param>
/// <param name="startIndex">串匹配的开始位置</param>
/// <returns>子串在主串中的位置,不存在返回-1.</returns>
int IndexOf(IString value, int startIndex = 0);

/// <summary>
/// 填充字符串
/// </summary>
/// <param name="totalWidth">结果字符串中的字符数</param>
/// <param name="paddingChar">填充字符</param>
/// <returns>如果totalWidth小于此实例的长度,则为与此实例相同的新IString。</returns>
IString PadLeft(int totalWidth, char paddingChar);

/// <summary>
/// 去掉两端的空格
/// </summary>
/// <returns>从当前对象的开始和末尾移除所有空白字符后保留的字符串。</returns>
IString Trim();
}
}

1.2 串的存储与实现

串的存储结构与线性表相同,分为两种:

  • 顺序存储:char类型的数组。由于数组是定长的,就存在一个预定义的最大串长度,它规定在串值后面加一个不计入串长度的结束符,比如’\0’来表示串值的终结。
  • 链式存储:SlinkList<char> (浪费存储空间)
图3 顺序串类图
using System;

namespace LinearStruct
{
/// <summary>
/// 串抽象数据类型的实现--顺序串
/// </summary>
public class SeqString : IString
{
protected readonly char[] CStr; //字符串以'\0'结束

/// <summary>
/// 初始化SeqString类的新实例
/// </summary>
public SeqString()
{
CStr = new char[] { '\0' };
}

/// <summary>
/// 初始化SeqString类的新实例
/// </summary>
/// <param name="s">初始字符串</param>
public SeqString(string s)
{
if (s == null)
throw new ArgumentNullException();

int len = s.Length;
CStr = new char[len + 1];
for (int i = 0; i < len; i++)
{
CStr[i] = s[i];
}
CStr[len] = '\0';
}

/// <summary>
/// 初始化SeqString类的新实例(只能在类的内部使用)
/// </summary>
/// <param name="length">串的长度</param>
protected SeqString(int length)
{
if (length < 0)
throw new ArgumentOutOfRangeException();

CStr = new char[length + 1];
CStr[length] = '\0';
}

/// <summary>
/// 获取串的长度
/// </summary>
public int Length
{
get
{
int i = 0;
while (CStr[i] != '\0')
i++;
return i;
}
}

/// <summary>
/// 获取或设置指定索引处的字符
/// </summary>
/// <param name="index">要获取或设置的字符从零开始的索引</param>
/// <returns>指定索引处的字符</returns>
public char this[int index]
{
get
{
if (index < 0 || index > Length - 1)
throw new IndexOutOfRangeException();
return CStr[index];
}
set
{
if (index < 0 || index > Length - 1)
throw new IndexOutOfRangeException();
CStr[index] = value;
}
}

/// <summary>
/// 在指定位置插入子串
/// </summary>
/// <param name="startIndex">插入的位置</param>
/// <param name="s">插入的子串</param>
/// <returns>插入串后得到的新串</returns>
public IString Insert(int startIndex, IString s)
{
if (s == null)
throw new ArgumentNullException();
if (startIndex < 0 || startIndex > Length)
throw new ArgumentOutOfRangeException();

int len1 = Length;
int len2 = s.Length;
SeqString str = new SeqString(len1 + len2);
for (int i = 0; i < startIndex; i++)
{
str.CStr[i] = CStr[i]; //注意str[i]直接使用是错误的
}
for (int i = 0; i < len2; i++)
{
str.CStr[i + startIndex] = s[i];
}
for (int i = startIndex; i < len1; i++)
{
str.CStr[i + len2] = CStr[i];
}
return str;
}

/// <summary>
/// 串连接
/// </summary>
/// <param name="s">在尾部要连接的串</param>
/// <returns>连接后得到的新串</returns>
public IString Concat(IString s)
{
if (s == null)
throw new ArgumentNullException();

return Insert(Length, s);
}

/// <summary>
/// 串连接运算符的重载
/// </summary>
/// <param name="s1">第一个串</param>
/// <param name="s2">第二个串</param>
/// <returns>连接后得到的新串</returns>
public static SeqString operator +(SeqString s1, SeqString s2)
{
if (s1 == null || s2 == null)
throw new ArgumentNullException();

return s1.Concat(s2) as SeqString;
}
/// <summary>
/// 在指定位置移除子串
/// </summary>
/// <param name="startIndex">移除的位置</param>
/// <param name="count">移除的长度</param>
/// <returns>移除后得到的新串</returns>
public IString Remove(int startIndex, int count)
{
if (startIndex < 0 || startIndex > Length - 1)
throw new ArgumentOutOfRangeException();
if (count < 0)
throw new ArgumentOutOfRangeException();

int len = Length;
int left = len - startIndex; //最多移除字符个数
count = (left < count) ? left : count; //实际移除字符个数
SeqString str = new SeqString(len - count);
for (int i = 0; i < startIndex; i++)
{
str.CStr[i] = CStr[i];
}
for (int i = startIndex + count; i < len; i++)
{
str.CStr[i - count] = CStr[i];
}
return str;
}

/// <summary>
/// 在指定位置取子串
/// </summary>
/// <param name="startIndex">取子串的位置</param>
/// <param name="count">子串的长度</param>
/// <returns>取得的子串</returns>
public IString SubString(int startIndex, int count)
{
if (startIndex < 0 || startIndex > Length - 1)
throw new ArgumentOutOfRangeException();
if (count < 0)
throw new ArgumentOutOfRangeException();

int left = Length - startIndex; //取子串最大长度
count = (left < count) ? left : count; //子串实际长度
SeqString str = new SeqString(count);
for (int i = 0; i < count; i++)
str.CStr[i] = CStr[i + startIndex];
return str;
}

/// <summary>
/// 当前串的拷贝
/// </summary>
/// <returns>当前串的拷贝</returns>
public IString Clone()
{
int len = Length;
SeqString str = new SeqString(len);
for (int i = 0; i < len; i++)
str.CStr[i] = CStr[i];
return str;
}

/// <summary>
/// 填充字符串
/// </summary>
/// <param name="totalWidth">结果字符串中的字符数</param>
/// <param name="paddingChar">填充字符</param>
/// <returns>
/// 如果totalWidth小于此实例的长度,则为与此实例相同的新IString。
/// </returns>
/// <remarks>
/// 异常:
/// System.ArgumentOutOfRangeException:totalWidth 小于零。
/// </remarks>
public IString PadLeft(int totalWidth, char paddingChar)
{
if (totalWidth < 0)
throw new ArgumentOutOfRangeException();

int len = Length;
if (len >= totalWidth)
return Clone();

SeqString result = new SeqString(totalWidth);
int left = totalWidth - len;
for (int i = 0; i < left; i++)
{
result.CStr[i] = paddingChar;
}
for (int i = 0; i < len; i++)
{
result.CStr[i + left] = CStr[i];
}
return result;
}

/// <summary>
/// SeqString类的输出字符串
/// </summary>
/// <returns>SeqString类的输出字符串</returns>
public override string ToString()
{
string str = string.Empty;
for (int i = 0, len = Length; i < len; i++)
str += CStr[i];
return str;
}

/// <summary>
/// 串的匹配
/// </summary>
/// <param name="value">要匹配的子串</param>
/// <param name="startIndex">匹配的起始位置</param>
/// <returns>子串在主串中的位置,不存在返回-1.</returns>
public int IndexOf(IString value, int startIndex = 0)
{
if (value == null || value.Length == 0)
throw new Exception("匹配字符串为null或空.");
if (startIndex < 0 || startIndex > value.Length - 1)
throw new ArgumentOutOfRangeException();

int len1 = Length;
int len2 = value.Length;
for (int i = startIndex; i <= len1 - len2; i++)
{
if (CStr[i] == value[0])
{
int j;
for (j = 1; j < len2; j++)
{
if (CStr[j + i] != value[j])
break;
}
if (j == len2)
return i;
}
}
return -1;
}

/// <summary>
/// 移除所有前导空白字符和尾部空白字符。
/// </summary>
/// <returns>从当前对象的开始和末尾移除所有空白字符后保留的字符串。</returns>
public IString Trim()
{
//返回移除所有前导空白字符和尾部空白字符后保留的字符串.
int left, right;
int len = Length;
for (left = 0; left < len; left++)
{
if (CStr[left] != ' ')
break;
}
if (left == len)
return new SeqString();

for (right = len - 1; right >= 0; right--)
{
if (CStr[right] != ' ')
break;
}
return SubString(left, right - left + 1);
}
}
}

例子:

class Program
{

static void Main(string[] args)
{
string S = "teacher and student all like tea.";
IString str = new SeqString(S);
Console.WriteLine("原字符串:{0}", str);
// 原字符串: teacher and student all like tea.

IString str2 = str;
IString str3 = str.Clone();
str2[0] = 'm';
Console.WriteLine("没调用Clone方法:{0}", str);
// 没调用Clone方法: meacher and student all like tea.
Console.WriteLine("调用Clone方法:{0}", str3);
// 调用Clone方法: teacher and student all like tea.

str = new SeqString(S);
IString str4 = new SeqString("mother ");
Console.WriteLine(str.Insert(0, str4));
// mother teacher and student all like tea.
Console.WriteLine(str.Insert(3, str4));
// teamother cher and student all like tea.

Console.WriteLine(str.Remove(3, 2));
// teaer and student all like tea.
Console.WriteLine(str.Remove(3, 10));
// teatudent all like tea.

Console.WriteLine(str.Concat(str4));
// teacher and student all like tea.mother
Console.WriteLine((SeqString) str4 + (SeqString) str);
// mother teacher and student all like tea.

Console.WriteLine(str.SubString(3, 0));
//
Console.WriteLine(str.SubString(3, 4));
// cher
Console.WriteLine(str.SubString(3, 10));
// cher and s

IString parS1 = new SeqString("ea");
IString parS2 = new SeqString("hk");
Console.WriteLine(str.IndexOf(parS1));
// 1
Console.WriteLine(str.IndexOf(parS2));
// -1

IString str5 = new SeqString(" a ");
Console.WriteLine(str5.Length);
// 6
Console.WriteLine(str5.Trim().Length);
// 1
}

1.3 C# 中的字符串

字符串为C#语言中一种默认的数据类型,该种类型提供了大量的方法以供程序员使用。

C# 中存在两种字符串,一种是不可变字符的字符串(string)、另一种是可变字符的字符串(StringBuilder)。

例子:不可变字符串

class Program
{

static void Main(string[] args)
{
string str = "This is a string";
string substr = str.Substring(0, 3);
Console.WriteLine(substr);
// Thi
string insertstr = str.Insert(3, "InsertString");
Console.WriteLine(insertstr);
// ThiInsertStrings is a string
string removestr = str.Remove(3, 4);
Console.WriteLine(removestr);
// Thi a string
int length = str.Length;
Console.WriteLine(length);
// 16
bool flag1 = (str == "This is a String") ? true : false;
Console.WriteLine(flag1);
// False
bool flag2 = (str != "This is a String") ? true : false;
Console.WriteLine(flag2);
// True
string catstr = str + "and other string";
Console.WriteLine(catstr);
// This is a stringand other string
int index = str.IndexOf("is");
Console.WriteLine(index);
// 2
string replacestr = str.Replace("is", "IS");
Console.WriteLine(replacestr);
// ThIS IS a string
char c = str[3];
Console.WriteLine(c);
// s
// str[3] = 'c';
// 错误 CS0200 无法为属性或索引器“string.this[int]”赋值 - 它是只读的
}
}

例子:可变字符串

class Program
{

static void Main(string[] args)
{
StringBuilder strb = new StringBuilder("abcdef");
strb[0] = 'M';
Console.WriteLine(strb);
// Mbcdef
}
}

2. 整数集合

2.1 整数集合的定义与操作

(1)整数集合的定义

由若干互不相同的正整数组成的集合,其中全集为 0 至 MaxRange,MaxRange 为构成该集合元素的最大值。

(2)整数集合的操作

  • 向集合中添加元素
  • 删除集合中的元素
  • 判断元素是否属于该集合
  • 得到集合中的所有元素
  • 求两个集合的并集
  • 求两个集合的交集
  • 求两个集合的差集
  • 求集合的补集
图4 整数集合接口
namespace LinearStruct
{
/// <summary>
/// 集合的抽象数据类型
/// </summary>
/// <typeparam name="T">集合元素的类型</typeparam>
public interface ISet<T>
{
/// <summary>
/// 向集合中添加元素
/// </summary>
/// <param name="elt">要插入到集合的元素</param>
void Insert(T elt);
/// <summary>
/// 删除集合中的元素
/// </summary>
/// <param name="elt">要删除的集合元素</param>
void Remove(T elt);
/// <summary>
/// 判断元素是否属于该集合
/// </summary>
/// <param name="elt">要判断的集合元素</param>
/// <returns>若属于该集合返回true,否则返回false.</returns>
bool IsMember(T elt);
/// <summary>
/// 得到集合中的所有元素
/// </summary>
/// <returns>表示集合中所有元素的字符串.</returns>
string GetElements();
/// <summary>
/// 求两个集合的并集
/// </summary>
/// <param name="b">与其求并的集合</param>
/// <returns>两个集合的并集</returns>
ISet<T> Union(ISet<T> b);
/// <summary>
/// 求两个集合的交集
/// </summary>
/// <param name="b">与其求交的集合</param>
/// <returns>两个集合的交集</returns>
ISet<T> Intersect(ISet<T> b);
/// <summary>
/// 求两个集合的差集
/// </summary>
/// <param name="b">与其求差的集合</param>
/// <returns>两个集合的差集</returns>
ISet<T> DiffSet(ISet<T> b);
/// <summary>
/// 求集合的补集
/// </summary>
/// <returns>集合的补集</returns>
ISet<T> Complement();
}
}

2.2 整数集合的存储与实现

(1)利用数组进行实现

若整数集合为,则其子集也必须存放在长度为的数组中。

  • 全集:uint[] A = new uint[n]; 元素全部赋值1。
  • 空集为:uint[] A = new uint[n]; 元素全部赋值0。

例子:

图5 利用数组存储整数集合

(2)利用位运算进行实现

例子:

图6 利用位运算存储整数集合
图7 整数集合类图
using System;

namespace LinearStruct
{
/// <summary>
/// 用整数集合实现集合的抽象数据类型
/// </summary>
public class IntSet : ISet<uint> //uint 32位无符号整数
{
private readonly uint[] _bitSet;//位数组

/// <summary>
/// 获取整数集合中的最大元素,全集为0至MaxRange
/// </summary>
public uint MaxRange { get; }

/// <summary>
/// 初始化IntSet类的新实例
/// </summary>
/// <param name="maxRge">整数集合中的最大元素</param>
public IntSet(uint maxRge)
{
MaxRange = maxRge;
_bitSet = new uint[MaxRange / 32 + 1];
for (int i = 0; i < _bitSet.Length; i++)
{
_bitSet[i] = 0;//当前集合为空集
}
}

/// <summary>
/// 获取元素在位数组中的索引号
/// </summary>
/// <param name="elt">获取在位数组中索引号的元素</param>
/// <returns>元素在位数组中的索引号</returns>
private uint ArrayIndex(uint elt)
{
if (elt > MaxRange)
throw new ArgumentOutOfRangeException();

return elt / 32;
}

/// <summary>
/// 获取元素对应位置的整数
/// </summary>
/// <param name="elt">获取对应位置整数的元素</param>
/// <returns>元素对应位置的整数</returns>
private uint BitMask(uint elt)
{
if (elt > MaxRange)
throw new ArgumentOutOfRangeException();

return (uint)Math.Pow(2, elt % 32);
}

/// <summary>
/// 向集合中添加元素
/// </summary>
/// <param name="elt">要插入到集合的元素</param>
public void Insert(uint elt)
{
if (elt > MaxRange)
throw new ArgumentOutOfRangeException();
_bitSet[ArrayIndex(elt)] |= BitMask(elt);
}

/// <summary>
/// 删除集合中的元素
/// </summary>
/// <param name="elt">要删除的集合元素</param>
public void Remove(uint elt)
{
if (elt > MaxRange)
throw new ArgumentOutOfRangeException();

_bitSet[ArrayIndex(elt)] &= ~BitMask(elt);
}

/// <summary>
/// 判断元素是否属于该集合
/// </summary>
/// <param name="elt">要判断的集合元素</param>
/// <returns>若属于该集合返回true,否则返回false.</returns>
public bool IsMember(uint elt)
{
if (elt > MaxRange)
return false;
uint i = _bitSet[ArrayIndex(elt)] & BitMask(elt);
return i != 0;
}

/// <summary>
/// 获取对应二进制字符串
/// </summary>
/// <returns>对应二进制字符串</returns>
public string GetBitString()
{
string temp = string.Empty;
for (int i = 0; i < _bitSet.Length; i++)
{
temp = Convert.ToString(_bitSet[i], 2).PadLeft(32, '0') + temp;
}
return temp.Remove(0, 32 - (int)(MaxRange % 32 + 1));
}

/// <summary>
/// 得到集合中的所有元素
/// </summary>
/// <returns>表示集合中所有元素的字符串.</returns>
public string GetElements()
{
string s = GetBitString();
string temp = string.Empty;
int j = 0;
for (int i = s.Length - 1; i >= 0; i--)
{
if (s[i] == '1')
temp += j + " ";
j++;
}
return temp.Trim();
}

/// <summary>
/// 求两个集合的并集
/// </summary>
/// <param name="b">与其求并的集合</param>
/// <returns>两个集合的并集</returns>
public IntSet Union(IntSet b)
{
if (b == null)
throw new ArgumentNullException();
if (b.MaxRange != MaxRange)
throw new Exception("两个集合范围不同.");

IntSet temp = new IntSet(MaxRange);

for (int i = 0; i < _bitSet.Length; i++)
{
temp._bitSet[i] = _bitSet[i] | b._bitSet[i];
}
return temp;
}

/// <summary>
/// 求两个集合的交集
/// </summary>
/// <param name="b">与其求交的集合</param>
/// <returns>两个集合的交集</returns>
public IntSet Intersect(IntSet b)
{
if (b == null)
throw new ArgumentNullException();
if (MaxRange != b.MaxRange)
throw new Exception("两个集合范围不同.");

IntSet temp = new IntSet(MaxRange);
for (int i = 0; i < _bitSet.Length; i++)
{
temp._bitSet[i] = _bitSet[i] & b._bitSet[i];
}
return temp;
}

/// <summary>
/// 求两个集合的差集
/// </summary>
/// <param name="b">与其求差的集合</param>
/// <returns>两个集合的差集</returns>
public IntSet DiffSet(IntSet b)
{
if (b == null)
throw new ArgumentNullException();
if (MaxRange != b.MaxRange)
throw new Exception("两集合范围不同.");

IntSet temp = new IntSet(MaxRange);
for (int i = 0; i < _bitSet.Length; i++)
{
temp._bitSet[i] = _bitSet[i] & (~b._bitSet[i]);
}
return temp;
}

/// <summary>
/// 求集合的补集
/// </summary>
/// <returns>集合的补集</returns>
public IntSet Complement()
{
IntSet temp = new IntSet(MaxRange);
for (int i = 0; i < _bitSet.Length; i++)
{
temp._bitSet[i] = ~_bitSet[i];
}
return temp;
}

ISet<uint> ISet<uint>.Union(ISet<uint> b)
{
return Union(b as IntSet);
}

ISet<uint> ISet<uint>.Intersect(ISet<uint> b)
{
return Intersect(b as IntSet);
}

ISet<uint> ISet<uint>.DiffSet(ISet<uint> b)
{
return DiffSet(b as IntSet);
}

ISet<uint> ISet<uint>.Complement()
{
return Complement();
}
}
}

例子:

class Program
{

static void Main(string[] args)
{
IntSet setA = new IntSet(33);
IntSet setB = new IntSet(33);
setA.Insert(5);
setA.Insert(30);
setA.Insert(23);
setB.Insert(5);
setB.Insert(24);
setB.Insert(9);
Console.WriteLine("A集合:{0};{1}", setA.GetBitString(), setA.GetElements());
//A集合: 0001000000100000000000000000100000; 5 23 30

Console.WriteLine("B集合:{0};{1}", setB.GetBitString(), setB.GetElements());
// B集合: 0000000001000000000000001000100000; 5 9 24

IntSet setC = setA.Union(setB);
Console.WriteLine("A并B :{0}:{1}", setC.GetBitString(), setC.GetElements());
// A并B: 0001000001100000000000001000100000:5 9 23 24 30

setC = setA.Intersect(setB);
Console.WriteLine("A交B :{0}:{1}", setC.GetBitString(), setC.GetElements());
// A交B: 0000000000000000000000000000100000:5

setC = setA.DiffSet(setB);
Console.WriteLine("A差B :{0}:{1}", setC.GetBitString(), setC.GetElements());
// A差B: 0001000000100000000000000000000000:23 30

setC = setA.Complement();
Console.WriteLine("A的补:{0}:{1}", setC.GetBitString(), setC.GetElements());
// A的补: 1110111111011111111111111111011111:0 1 2 3 4 6 7 8 9 10 11 12 13 14 15 16
// 17 18 19 20 21 22 24 25 26 27 28 29 31 32 33
}
}

2.3 C# 中整数集合的应用

namespace System.Drawing
{
//指定应用到文本的字形信息。
public enum FontStyle
{
Regular = 0, // 普通文本。
Bold = 1, // 加粗文本。
Italic = 2, // 倾斜文本。
Underline = 4, // 带下划线的文本。
Strikeout = 8, // 中间有直线通过的文本。
}
}

例子:

FontStyle fs = FontStyle.Bold | FontStyle.Strikeout;
Font fnt = new Font("宋体", 12f, fs);
this.label1.Font = fnt;

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C#委托四(匿名方法)
ISerializable用法(初级)
Orleans[NET Core 3.1] 学习笔记(四)( 1 )创建项目
C# 登录简单网站尝试 — Windows Live
C# Left, Right and Mid函数
求两字符串的公共子串
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服